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
How to Sort Pandas Dataframe from One Column
Why Does Range(Start, End) Not Include End
How to "Watch" a File for Modification/Change
What Is the Easiest Way to Detect Key Presses in Python 3 on a Linux MAChine
How to Properly Write to Fifos in Python
Permission Denied When Executing Python File in Linux
How to Delete a Directory Created with Tempfile.Mkdtemp
Trouble Connecting to Phantomjs Webdriver Using Python and Selenium
How to Get Process's Grandparent Id
Sharing Psycopg2/Libpq Connections Across Processes
Proxies With Python 'Requests' Module
Groupby Pandas Dataframe and Select Most Common Value
Equivalent to Gettickcount() on Linux
Getting Another Program's Output as Input on the Fly
Linux/Python: Encoding a Unicode String for Print
Cant Get Pyperclip to Use Copy and Paste Modules on Python3