Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding the nearest value and return the index of array in Python

I found this post: Python: finding an element in an array

and it's about returning the index of an array through matching the values.

On the other hand, what I am thinking of doing is similar but different. I would like to find the nearest value for the target value. For example I am looking for 4.2 but I know in the array there is no 4.2 but I want to return the index of the value 4.1 instead of 4.4.

What would be the fastest way of doing it?

I am thinking of doing it the old way like how I used to do it with Matlab, which is using the array A where I want to get the index from to minus the target value and take the absolute of it, then select the min. Something like this:-

[~,idx] = min(abs(A - target))

That is Matlab code but I am newbie in Python so I am thinking, is there a fast way of doing it in Python?

Thank you so much for your help!

like image 274
Harry MacDowel Avatar asked Jan 18 '12 17:01

Harry MacDowel


People also ask

How do you find the index of an array in Python?

Python has a method to search for an element in an array, known as index(). If you would run x. index('p') you would get zero as output (first index).

How do you find the value closest to a value in Python?

We can find the nearest value in the list by using the min() function. Define a function that calculates the difference between a value in the list and the given value and returns the absolute value of the result. Then call the min() function which returns the closest value to the given value.


3 Answers

This is similar to using bisect_left, but it'll allow you to pass in an array of targets

def find_closest(A, target):
    #A must be sorted
    idx = A.searchsorted(target)
    idx = np.clip(idx, 1, len(A)-1)
    left = A[idx-1]
    right = A[idx]
    idx -= target - left < right - target
    return idx

Some explanation:

First the general case: idx = A.searchsorted(target) returns an index for each target such that target is between A[index - 1] and A[index]. I call these left and right so we know that left < target <= right. target - left < right - target is True (or 1) when target is closer to left and False (or 0) when target is closer to right.

Now the special case: when target is less than all the elements of A, idx = 0. idx = np.clip(idx, 1, len(A)-1) replaces all values of idx < 1 with 1, so idx=1. In this case left = A[0], right = A[1] and we know that target <= left <= right. Therefor we know that target - left <= 0 and right - target >= 0 so target - left < right - target is True unless target == left == right and idx - True = 0.

There is another special case if target is greater than all the elements of A, In that case idx = A.searchsorted(target) and np.clip(idx, 1, len(A)-1) replaces len(A) with len(A) - 1 so idx=len(A) -1 and target - left < right - target ends up False so idx returns len(A) -1. I'll let you work though the logic on your own.

For example:

In [163]: A = np.arange(0, 20.)

In [164]: target = np.array([-2, 100., 2., 2.4, 2.5, 2.6])

In [165]: find_closest(A, target)
Out[165]: array([ 0, 19,  2,  2,  3,  3])
like image 177
Bi Rico Avatar answered Oct 05 '22 23:10

Bi Rico


The corresponding Numpy code is almost the same, except you use numpy.argmin to find the minimum index.

idx = numpy.argmin(numpy.abs(A - target))
like image 35
kennytm Avatar answered Oct 06 '22 00:10

kennytm


Well, more than 2 years have gone by and I have found a very simple implementation from this URL in fact: Find nearest value in numpy array

The implementation is:

def getnearpos(array,value):
    idx = (np.abs(array-value)).argmin()
    return idx   

Cheers!!

like image 23
Harry MacDowel Avatar answered Oct 06 '22 00:10

Harry MacDowel