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

Har*_*wel 34 python numpy python-3.x

我发现这篇文章:Python:在数组中查找元素

它是关于通过匹配值返回数组的索引.

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

这样做的最快方法是什么?

我正在考虑用旧的方式来做它,就像我以前用Matlab做的那样,它使用数组A,我想从索引到减去目标值并取绝对值,然后选择min.像这样: -

[~,idx] = min(abs(A - target))
Run Code Online (Sandbox Code Playgroud)

这是Matlab代码,但我是Python的新手,所以我在想,有没有一种快速的方法在Python中做到这一点?

非常感谢你的帮助!

ken*_*ytm 32

除了numpy.argmin用于查找最小索引之外,相应的Numpy代码几乎相同.

idx = numpy.argmin(numpy.abs(A - target))
Run Code Online (Sandbox Code Playgroud)

  • 如果输入数组按排序顺序,那么`numpy.searchsorted`也很方便(也更有效). (3认同)

Bi *_*ico 32

这类似于使用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
Run Code Online (Sandbox Code Playgroud)

一些解释:

第一一般情况下:idx = A.searchsorted(target)返回每个的索引target,使得target之间A[index - 1]A[index].我打电话给这些left,right所以我们知道left < target <= right.target - left < right - targetTrue(或1)时的目标更接近leftFalse(或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 <= 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)len(A) - 1so 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])
Run Code Online (Sandbox Code Playgroud)


Har*_*wel 6

好吧,超过2年已经过去了,事实上我从这个URL找到了一个非常简单的实现:在numpy数组中查找最接近的值

实施是:

def getnearpos(array,value):
    idx = (np.abs(array-value)).argmin()
    return idx   
Run Code Online (Sandbox Code Playgroud)

干杯!!


kir*_*off 5

测试并计时了两种解决方案:

idx = np.searchsorted(sw, sCut)
Run Code Online (Sandbox Code Playgroud)

idx = np.argmin(np.abs(sw - sCut))
Run Code Online (Sandbox Code Playgroud)

用于以耗时的方法进行计算。第二种方案的计算时间为113秒,第一种方案的计算时间为132秒