这类似于使用 bisect_left,但它允许您传入一个目标数组
def find_closest(A, target):
#A must be sorted
idx = A.searchsorted(target)
idx = np.clip(idx, 1, len(A)-1)
left = A[idx-1]
right = A[idx]
idx -= target - left < right - target
return idx
一些解释:
首先是一般情况:idx = A.searchsorted(target)为每个target返回一个索引,这样target就在A[index - 1]和A[index]之间。我称这些为left 和right,所以我们知道left < target <= right。当目标更接近left 时target - left < right - target 为True(或1),当目标更接近right 时False(或0)。
现在是特殊情况:当target 小于A、idx = 0 的所有元素时。 idx = np.clip(idx, 1, len(A)-1) 将 idx idx=1。在这种情况下left = A[0],right = A[1],我们知道target <= left <= right。因此我们知道target - left <= 0 和right - target >= 0 所以target - left < right - target 是True 除非target == left == right 和idx - True = 0。
如果target大于A的所有元素还有另一种特殊情况,在这种情况下idx = A.searchsorted(target)和np.clip(idx, 1, len(A)-1)
用len(A)替换len(A) - 1所以idx=len(A) -1和target - left < right - target结束向上 False 所以 idx 返回 len(A) -1。我会让你自己处理逻辑。
例如:
In [163]: A = np.arange(0, 20.)
In [164]: target = np.array([-2, 100., 2., 2.4, 2.5, 2.6])
In [165]: find_closest(A, target)
Out[165]: array([ 0, 19, 2, 2, 3, 3])