这里的目标是速度 - 我试图摆脱有问题的阵列循环。但是可以假设这两个数组已经排序。
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)
但即使这样做也有点慢,因为会进行大量不必要的减法。
答案 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))