查找最接近的值并在Python中返回数组的索引
问题内容:
我发现了这篇文章:Python:在数组中查找元素
这是通过匹配值来返回数组的索引。
另一方面,我的想法是相似但不同。我想找到最接近目标值的值。例如,我正在寻找4.2,但是我知道数组中没有4.2,但是我想返回值4.1的索引而不是4.4。
最快的方法是什么?
我正在考虑以旧方式进行操作,就像我以前使用Matlab一样,正在使用数组A,我要从中获取索引以减去目标值并取其绝对值,然后选择最小值。像这样的东西:
[~,idx] = min(abs(A - target))
那是Matlab代码,但是我是Python的新手,所以我在想,是否有快速的方法可以在Python中完成呢?
非常感谢你的帮助!
问题答案:
这类似于使用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
。target - left < right - target
是True
(或1)时的目标更接近left
和False
(或0)时的目标更接近right
。
现在的特殊情况:当target
小于所有的元素A
,idx = 0
。idx = np.clip(idx, 1, len(A)-1)
将所有idx
<1的值替换为1,因此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
soidx=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])