查找最接近的值并返回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 <= 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的所有值replace为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)
replace为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])
除了使用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))