在两个numpy数组中查找最接近的值

时间:2017-06-13 15:45:41

标签: python arrays numpy

这里的目标是速度 - 我试图摆脱有问题的阵列循环。但是可以假设这两个数组已经排序。

a = np.arange(10)
b = np.array([2.3, 3.5, 5.8, 13])
c = somefunc(a,b)

现在somefunc应该找到a的索引,b中的值也是最接近的,即

In []: c
Out[]: array([2, 3or4, 6, 9])  #3 or 4 depending on python2 or 3

再次,这可以通过循环来完成,但我正在寻找更快的东西。我采用绝对差异类型方法非常接近,例如:

np.argmin(np.abs(a[:, np.newaxis] - b), axis=0)

但即使这样做也有点慢,因为会进行大量不必要的减法。

3 个答案:

答案 0 :(得分:0)

跟踪两个指针,一个用于a的当前索引,另一个用于b。当我们递增指针a时,我们跟踪指向的元素之间的最小差异和索引,直到指向了... pointed_b。再次更新最小差异和索引(如果有更改)。我们有第一个元素的答案。通过增加b的指针继续搜索,并从我们离开的地方拿起指针a。

复杂性:O(len a + len b),因此线性

答案 1 :(得分:0)

scipy.spatial.cKDTree是解决此问题的最简单方法;矢量化,非常适合您的应用;但鉴于您的数据已经排序,理论上并不理想。

或者,您可以使用numpy.searchsorted。使用它来查找左侧或右侧插入点,然后比较该点和下一个点以找到最近的点。

答案 2 :(得分:-1)

因此,使用@Eelco的建议来使用searchsorted,我得到了以下内容,它使用比向量方法上的np.argmin更大的数据集更快:

def finder(a, b):
    dup = np.searchsorted(a, b)
    uni = np.unique(dup)
    uni = uni[uni < a.shape[0]]
    ret_b = np.zeros(uni.shape[0])
    for idx, val in enumerate(uni):
        bw = np.argmin(np.abs(a[val]-b[dup == val]))
        tt = dup == val
        ret_b[idx] = np.where(tt == True)[0][bw]
    return np.column_stack((uni, ret_b))