查找最接近的值并返回Python中的数组索引

我发现这篇文章: Python:在数组中find一个元素

它是通过匹配值来返回一个数组的索引。

另一方面,我所做的是相似但不同的。 我想find目标值的最接近的值。 例如我正在寻找4.2,但我知道在数组中没有4.2,但我想要返回值4.1的索引而不是4.4。

什么是最快的方式呢?

我正在考虑像以前那样用Matlab来做这个事情,它使用数组A,我想从索引中减去目标值,然后取绝对值,然后select最小值。 像这样的东西: –

[~,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调用,所以我们知道left < target <= righttarget - left < right - targetTrue (或1),当目标更接近left时为False (或0),当目标更接近right

现在特例:当target小于A所有元素时, idx = 0idx = np.clip(idx, 1, len(A)-1)idx <1的所有值replace为1,所以idx=1 。 在这种情况下, left = A[0]right = A[1] ,我们知道target <= left <= right 。 因此,我们知道target - left <= 0right - target >= 0因此target - left < right - targetTrue除非target == left == rightidx - True = 0

如果target大于A所有元素,则还有另外一种特殊情况,在这种情况下, idx = A.searchsorted(target)np.clip(idx, 1, len(A)-1)len(A)replace为len(A) - 1所以idx=len(A) -1target - 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]) 

除了使用numpy.argmin来查找最小索引之外,相应的Numpy代码几乎是一样的。

 idx = numpy.argmin(numpy.abs(A - target)) 

testing和定时两个解决scheme:

 idx = np.searchsorted(sw, sCut) 

 idx = np.argmin(np.abs(sw - sCut)) 

用于计算时间昂贵的方法。 第二种解决scheme的计算时间为113 第一种计算的时间为132s

那么,超过2年过去了,我发现从这个URL实际上很简单的实现: 在numpy数组中find最接近的值

实施是:

 def getnearpos(array,value): idx = (np.abs(array-value)).argmin() return idx 

干杯!!

可能的scheme

 >>> a = [1.0, 3.2, -2.5, -3.1] >>> i = -1.5 >>> diff = [(abs(i - x),idx) for (idx,x) in enumerate(a)] >>> diff [(2.5, 0), (4.7, 1), (1.0, 2), (1.6, 3)] >>> diff.sort() >>> diff [(1.0, 2), (1.6, 3), (2.5, 0), (4.7, 1)] 

你会得到diff [0] [1]中最接近的值的索引

 def finder(myList, target) diff = '' index = None for i,num in enumerate(myList): if abs(target - num) < diff: diff = abs(target - num) index = i return index 

希望这可以帮助

编辑

如果你想要一个单线,那么你可能会更喜欢这个:

 min(L, key=lambda x: abs(target-x))