关于numpy:在python中查找最近的值并返回数组的索引

Finding the nearest value and return the index of array in Python

我找到了这篇文章:python:在数组中查找元素

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

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

最快的方法是什么?

我想用老方法来做,就像我以前用matlab做的一样,它使用数组a,我想从中得到索引,减去目标值,然后取其绝对值,然后选择最小值。类似这样:

1
[~,idx] = min(abs(A - target))

这是matlab代码,但我是python的新手,所以我想,在python中有没有一种快速的方法?

非常感谢你的帮助!


这类似于使用左平分,但它可以让你通过一系列的目标

1
2
3
4
5
6
7
8
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]之间。我把这些叫做leftright,所以我们知道left < target <= right。当目标靠近left时,target - left < right - targetTrue或1;当目标靠近right时,False或0。

现在的特例是:当target小于A的所有元素时,idx = 0idx = np.clip(idx, 1, len(A)-1)用1替换idx<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) - 1代替len(A),因此idx=len(A) -1target - left < right - targetFalse结束,因此idx返回len(A) -1。我会让你自己研究逻辑。

例如:

1
2
3
4
5
6
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代码几乎相同,除了使用numpy.argmin查找最小索引。

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


嗯,两年多过去了,事实上,我从这个URL找到了一个非常简单的实现:在numpy数组中查找最近的值

实施情况如下:

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

干杯!!


测试和定时两种解决方案:

1
idx = np.searchsorted(sw, sCut)

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

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


可能的解决方案:

1
2
3
4
5
6
7
8
>>> 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]中有最接近值的索引


1
2
3
4
5
6
7
8
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

希望这有帮助

编辑:

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

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