7

我想在一个大于我的搜索值的 numpy 数组中获取最近值的索引。示例:findNearestAbove(np.array([0.,1.,1.4,2.]), 1.5)应该返回 3(2 的索引)。

我知道我可以使用 获得最近的索引np.abs(a-value).argmin(),并且我发现它min(a[np.where(a-value >= 0.)[0]])返回了所需的数组值。因此,np.where(a == min(a[np.where(a-value >= 0.)[0]]))[0]可能会给我所需的索引。但是,这看起来相当复杂,我担心它可能会在多维数组的情况下中断。有什么建议可以改进吗?

4

4 回答 4

10

我相信你可以用np.searchsorted这个:

In [15]: np.searchsorted(a,[1.5,],side='right')[0]
Out[15]: 3

假设a是升序。

此方法也不适用于多维数组,但我不确定该用例在预期输出方面的工作方式。如果你能举一个你想象的例子,我也许可以根据这个目的进行调整。

注意:您也可以np.digitize用于此目的,尽管它执行线性搜索而不是二进制搜索,因此对于某些输入大小,它可能比单调慢searchsorted很多a

In [25]: np.digitize([1.5,], a, right=True)[0]
Out[25]: 3
于 2013-06-15T02:22:48.470 回答
7

这是一种方法(我假设最近的意思是价值而不是位置)

import numpy as np

def find_nearest_above(my_array, target):
    diff = my_array - target
    mask = np.ma.less_equal(diff, 0)
    # We need to mask the negative differences and zero
    # since we are looking for values above
    if np.all(mask):
        return None # returns None if target is greater than any value
    masked_diff = np.ma.masked_array(diff, mask)
    return masked_diff.argmin()

结果:

>>> find_nearest_above(np.array([0.,1.,1.4,2.]), 1.5)
3
>>> find_nearest_above(np.array([0.,1.,1.4,-2.]), -1.5)
0
>>> find_nearest_above(np.array([0., 1, 1.4, 2]), 3)
>>> 
于 2013-06-15T01:04:21.200 回答
0

这是一个解决方案,在查找数组中最接近但大于数字的值和索引时非常适合我(在速度等方面没有承诺):

def findNearestGreaterThan(searchVal, inputData):
    diff = inputData - searchVal
    diff[diff<0] = np.inf
    idx = diff.argmin()
    return idx, inputData[idx]

它也很容易适应最近但小于:

def findNearestLessThan(searchVal, inputData):
    diff = inputData - searchVal
    diff[diff>0] = -np.inf
    idx = diff.argmax()
    return idx, inputData[idx]
于 2016-07-08T14:15:15.630 回答
-3

这是执行此操作的正确方法:

>>> def argfind(array, predicate):
...     for i in xrange(array.shape[0]):
...         if predicate(array[i]):
...             return i
...     return False
...
>>> def find_nearest_above(array, value):
...     return argfind(array, lambda x: x > value)
...
>>> find_nearest_above(np.array([0.,1.,1.4,2.]), 1.5)
  > 3

这里的重点是,如果存在匹配的值,当满足这个值时,你就会得到答案。其他方法(包括您自己的,在问题中提出)将检查整个数组,这是浪费时间。

于 2013-06-14T23:29:12.547 回答