Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I would like to obtain the index of the nearest value in a numpy array which is greater than my search value. Example: findNearestAbove(np.array([0.,1.,1.4,2.]), 1.5) should return 3 (the index of 2.).

I know that I can get the nearest index with np.abs(a-value).argmin(), and I found out that min(a[np.where(a-value >= 0.)[0]]) returns the desired array value. Hence, np.where(a == min(a[np.where(a-value >= 0.)[0]]))[0] would probably give me the desired index. However, this looks rather convoluted, and I fear that it might break in the case of multi-dimensional arrays. Any suggestions how to improve this?

like image 740
maschu Avatar asked Jun 14 '13 22:06

maschu


2 Answers

I believe you can use np.searchsorted for this:

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

assuming a is in ascending order.

This method also won't work for multi-dimensional arrays, but I'm not sure exactly how that use case would work in terms of the expected output. If you could give an example of what you imagine, I might be able to adapt this to that purpose.

Note: you could also use np.digitize for this purpose, although it executes a linear rather than a binary search, so for certain input sizes, it can be a lot slower than searchsorted and requires that a be monotonic:

In [25]: np.digitize([1.5,], a, right=True)[0]
Out[25]: 3
like image 55
JoshAdel Avatar answered Nov 19 '22 05:11

JoshAdel


Here is one way (I am assuming that by nearest you mean in terms of value not location)

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()

Result:

>>> 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)
>>> 
like image 23
Akavall Avatar answered Nov 19 '22 06:11

Akavall