此答案解释了如何以有效的大型数组(稍微修改)的方式找到最近的(排序的)数组元素到a 单点:
def arg_nearest(array, value):
idx = np.searchsorted(array, value, side="left")
if idx > 0 and (idx == len(array) or math.fabs(value - array[idx-1]) < math.fabs(value - array[idx])):
return idx-1
else:
return idx
如果,我们想找到最接近点的数组元素(即第二个数组);除了使用循环吗?
一些测试用例:
>>> xx = [0.2, 0.8, 1.3, 1.5, 2.0, 3.1, 3.8, 3.9, 4.5, 5.1, 5.5]
>>> yy = [1, 2, 3, 4, 5]
>>> of_x_nearest_y(xx, yy)
[0.5, 2.0, 3.1, 3.9, 5.1]
>>> xx = [0.2, 0.8, 1.3, 1.5, 2.0, 3.1, 3.8, 3.9, 4.5, 5.1, 5.5]
>>> yy = [-2, -1, 4.6, 5.8]
>>> of_x_nearest_y(xx, yy)
[0.2, 0.2, 4.5, 5.5]
编辑:假设两个数组都是分类的,您可以通过排除以下已经匹配的值,即。>
def args_nearest(options, targets):
locs = np.zeros(targets.size, dtype=int)
prev = 0
for ii, tt in enumerate(targets):
locs[ii] = prev + arg_nearest(options[prev:], tt)
prev = locs[ii]
return locs
您可以进行很少的更改以将其扩展为value
中的一系列元素,例如So -
idx = np.searchsorted(xx, yy, side="left").clip(max=xx.size-1)
mask = (idx > 0) &
( (idx == len(xx)) | (np.fabs(yy - xx[idx-1]) < np.fabs(yy - xx[idx])) )
out = xx[idx-mask]
说明
命名法:array
是我们想要放置value
元素以保持array
的排序性质的数组。
将单个元素扩展到许多元素以进行搜索所需的更改:
1]剪辑以最大为np.searchsorted
获得的索引数组idx
。array.size-1
,因为对于value
中最大array
的元素,我们需要通过array
进行idx
。
2]介绍numpy
以替换math
以矢量化的方式进行这些操作。
3]用idx - mask
的技巧替换条件语句。在这种情况下,内部Python会将mask
转到int
数组,以与idx
的数据类型匹配。因此,所有True
元素成为1
,因此对于True
元素,我们将有效地具有idx-1
,这是原始代码中IF条件语句的True
情况。