Find Nearest Value in Numpy Array

Find nearest value in numpy array

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

Example usage:

array = np.random.random(10)
print(array)
# [ 0.21069679 0.61290182 0.63425412 0.84635244 0.91599191 0.00213826
# 0.17104965 0.56874386 0.57319379 0.28719469]

print(find_nearest(array, value=0.5))
# 0.568743859261

Finding nearest value in a numpy array produces nan output

Use nanargmin:

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

find nearest value above and below a value inside numpy array

For the nearest higher value, the difference of values_array - base_value will be positive when the value of your array is higher than base_value. Set all negative differences to infinity and then find the index of the lowest value.

def find_nearest_higher_key_value(key_value_object, base_value):
values_array = np.asarray(key_value_object)
diff = values_array - base_value
diff[diff < 0] = np.inf
idx = diff.argmin()
key = key_value_object.keys()[idx]
return key, value_array[idx]

For the lower value just switch the difference to base_value - values_array.

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

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

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

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

Closest element to a value (Elementwise, numpy array)

Is this what you are looking for?

np.where(np.abs(a - x0) < np.abs(b - x0), a, b)

Finding index of an item closest to the value in a list that's not entirely sorted

Try the following:

min(range(len(a)), key=lambda i: abs(a[i]-11.5))

For example:

>>> a = [25.75443, 26.7803, 25.79099, 24.17642, 24.3526, 22.79056, 20.84866, 19.49222, 18.38086, 18.0358, 16.57819, 15.71255, 14.79059, 13.64154, 13.09409, 12.18347, 11.33447, 10.32184, 9.544922, 8.813385, 8.181152, 6.983734, 6.048035, 5.505096, 4.65799]
>>> min(range(len(a)), key=lambda i: abs(a[i]-11.5))
16

Or to get the index and the value:

>>> min(enumerate(a), key=lambda x: abs(x[1]-11.5))
(16, 11.33447)

How to find the closest value in a list where x value for every value in a numpy array without looping

Use np.searchsorted to find the indices where the elements in x should be inserted into levels, maintaining the order. Assumes levels is sorted. This solution also works with a scalar or (multi-dimensional) array argument for x:

import numpy as np

def find_level(x, levels):
""" this assumes levels is sorted """
levels = np.asanyarray(levels)
indices = np.searchsorted(levels, np.floor(x))
indices = np.clip(indices, 0, len(levels) - 1) # clip out-of-bounds index
return levels[indices]

Testing it:

levels_ = [5, 6, 7, 8, 9, 10]

find_level(x=0.5, levels=levels_) # 5
find_level(x=7.01, levels=levels_) # 7
find_level(x=7.50, levels=levels_) # 7
find_level(x=7.99, levels=levels_) # 7
find_level(x=15, levels=levels_) # 10

x_ = np.array([[0.5, 7.01, 7.50, 7.99, 15],
[20, 30, 6.26, 5.01, 6.54]])
find_level(x_, levels_)
# array([[ 5, 7, 7, 7, 10],
# [10, 10, 6, 5, 6]])


Related Topics



Leave a reply



Submit