1

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?

2
  • Is true_values always sorted? If so, you might want to look into the searchsorted function. Commented Oct 24, 2015 at 16:49
  • The other answer you linked can be very easily converted to find the nearest, lower value. Alternatively, you can modify what you already have by insisting that array-value is negative. Commented Oct 24, 2015 at 16:57

2 Answers 2

5

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.