一尘不染

查找最接近数组2元素的数组1的元素

algorithm

此答案说明了如何以对大型数组有效的方式(略微修改)找到最接近(排序的)数组元素到
单个点

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

相反,如果要查找最接近一 点的数组元素(即第二个数组);除了使用for循环以外,是否有有效的方法(对于大型阵列而言是提高速度)?

一些测试用例:

>>> 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]

编辑:假设两个数组进行排序,你可以做一个 比一个更好的 完全 由下面这些已经匹配,即排除值天真的for循环

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

阅读 164

收藏
2020-07-28

共1个答案

一尘不染

您可以进行一些更改以将其扩展为中的元素数组value,如下所示-

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]截取idxnp.searchsorted最大获得的索引数组。of
array.size-1,因为对于其中的元素value大于的最大值array,我们需要将idx索引为array

2]介绍numpymath向量化方式进行替换以进行那些操作。

3]用技巧代替条件语句idx-mask。在这种情况下,Python内部将上转换mask为一个int数组以与的数据类型匹配idx。因此,所有True元素变为1,因此对于True我们将有效地具有的元素idx-1,这就是True原始代码中IF条件语句的情况。

2020-07-28