user2483176
user2483176

Reputation: 317

Infer nearest, smaller value in numpy array

I have an array of my_values for which I am trying infer the closest, smaller value in an array of true_values. Using the find_nearest function below doesn't accomplish what I want it to. How can I append this to find the nearest, smaller value?

import numpy as np

true_values = np.array([4.5, 3.0, 2.4, 1.2, 0.1])
my_values = np.array([0.8, 2.1, 3.01, 8.0, 0.2, 2.6, 2.1, 3.99, 1.3])

def find_nearest(array,value):
    idx = np.abs((array-value)).argmin()
    return array[idx]

nearest = []
for i in my_values:
    nearest.append(find_nearest(true_values,i))

print nearest
# [1.2, 2.4, 3.0, 4.5, 0.1, 2.4, 2.4, 4.5, 1.2]

But instead I would like the output to be

nearest = [0.1, 1.2, 3.0, 4.5, 0.1, 2.4, 1.2, 3.0, 1.2]

The first answer here: How to find nearest value that is greater in numpy array? accomplishes this for the nearest, larger value. Perhaps this can be changed to find the nearest, smaller value?

Upvotes: 1

Views: 1409

Answers (2)

Alex Riley
Alex Riley

Reputation: 177048

Using searchsorted is an option (as mentioned in the comment above and in the one of the answers in the linked question):

>>> true_values[-np.searchsorted(true_values[::-1], my_values)]
array([ 0.1,  1.2,  3. ,  4.5,  0.1,  2.4,  1.2,  3. ,  1.2])

Note that searchsorted requires the true_values to be sorted in ascending order. Here it's necessary to flip the order of your example array and then make the indices returned into negative integers for the fancy-indexing.

If true_values is not sorted (in any direction), you'll need to use np.argsort and the sorter parameter in searchsorted.

Upvotes: 5

Divakar
Divakar

Reputation: 221704

One approach with broadcasting -

true_values[(my_values[:,None] < true_values).argmin(1)]

Sample run -

In [33]: true_values
Out[33]: array([ 4.5,  3. ,  2.4,  1.2,  0.1])

In [34]: my_values
Out[34]: array([ 0.8 ,  2.1 ,  3.01,  8.  ,  0.2 ,  2.6 ,  2.1 ,  3.99,  1.3 ])

In [35]: true_values[(my_values[:,None] < true_values).argmin(1)]
Out[35]: array([ 0.1,  1.2,  3. ,  4.5,  0.1,  2.4,  1.2,  3. ,  1.2])

Upvotes: 2

Related Questions