关于python:如何找到numpy数组中更大的最接近的值?

How to find nearest value that is greater in numpy array?

我想获得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]可能会给我期望的指数。然而,这看起来相当复杂,我担心在多维数组的情况下它可能会崩溃。有什么改进的建议吗?


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

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

假设a按升序排列。

这个方法也不适用于多维数组,但我不确定该用例如何在预期的输出方面工作。如果你能举一个你所想象的例子,我也许能使它适应这个目的。

注意:您也可以使用np.digitize来实现这一目的,尽管它执行的是线性搜索而不是二进制搜索,因此对于某些输入大小,它可能比searchsorted慢得多,并且要求a是单调的:

1
2
In [25]: np.digitize([1.5,], a, right=True)[0]
Out[25]: 3


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

1
2
3
4
5
6
7
8
9
10
11
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()

结果:

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


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

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

它很容易适应最近的情况,但也低于:

1
2
3
4
5
def findNearestLessThan(searchVal, inputData):
    diff = inputData - searchVal
    diff[diff>0] = -np.inf
    idx = diff.argmax()
    return idx, inputData[idx]


以下是正确的方法:

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

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