可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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!
回答1:
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
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 - left 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
idx=1. In this case left = A[0]
, right = A[1]
and we know that target . Therefor we know that target - left and right - target >= 0
so target - left 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 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])
回答2:
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))
回答3:
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!!
回答4:
Tested and timed two solutions:
idx = np.searchsorted(sw, sCut)
and
idx = np.argmin(np.abs(sw - sCut))
for computation in a time expensive method. timing was 113s for computation with the second solution, and 132s for computation with the first one.
回答5:
Possible solution:
>>> a = [1.0, 3.2, -2.5, -3.1] >>> i = -1.5 >>> diff = [(abs(i - x),idx) for (idx,x) in enumerate(a)] >>> diff [(2.5, 0), (4.7, 1), (1.0, 2), (1.6, 3)] >>> diff.sort() >>> diff [(1.0, 2), (1.6, 3), (2.5, 0), (4.7, 1)]
You'll have the index of nearest value in diff[0][1]
回答6:
def finder(myList, target) diff = '' index = None for i,num in enumerate(myList): if abs(target - num)
Hope this helps
EDIT:
If you'd like a one-liner, then you might like this better:
min(L, key=lambda x: abs(target-x))