Reputation: 41
Using Python 2.7, I have an array of values that goes from ~0.000 to ~360.000 multiple times. I am trying to return all array indices with values closest to 147.010 (even duplicate values), so I can use each of these indices later on. For example, a smaller sample from one array is:
array([ 146.749, 147.249, 147.749, 146.749, 147.249, 147.749, 146.749, 147.263, 147.749, 146.472, 147.469, 148.471])
I am looking for an array, or list, of indices closest to 147.01, in this case would be:
1, 4, 7, 10
I have tried this:
min(range(len(array)), key=lambda i: abs(array[i]-some_value))
but this only returns one index, when multiple indices are needed. I looked but have not found a similar question or answer. Thank you for any help.
Upvotes: 4
Views: 3158
Reputation: 4379
If you like one-liners, take k = 147.01
then you can do:
print [i for i, v in enumerate(array) if abs(v - k) == min([abs(x - k) for x in array])]
Outputs: [1, 4]
It will print as many n indexes of elements equally close to k
. In your list elements at index 7, 10 are not equally close, can you double check those numbers?
EDIT: Let's see one by one, using the array from the question:
[146.749, 147.249, 147.749, 146.749, 147.249, 147.749, 146.749, 147.263, 147.749, 146.472, 147.469, 148.471]
Distances for elements at indexes: 1, 4, 7, 10:
index = 1, abs(147.249 - 147.01) = 0.239
index = 4, abs(147.249 - 147.01) = 0.239
index = 7, abs(147.263 - 147.01) = 0.253
index = 10, abs(147.469 - 147.01) = 0.459
According to these numbers, elements at indexes 1, 4
have a smaller distance from 147.01
than 7, 10
. Isn't this what you meant?
Upvotes: 0
Reputation: 43196
If you sort the array in the order the elements are away from the pivot, then you will be able to take the first k elements and those are the ones closest to the element you are looking at
def k_closest(sample, pivot, k):
return sorted(sample, key=lambda i: abs(i - pivot))[:k]
Example:
>>> l = [1,2,3,4]
>>> k_closest(l, 3, 2)
[3,2]
>>> k_closest(l, 3, 3)
[3,2,4]
To get the index of the elements as well, you can do this:
def k_closest(sample, pivot, k):
return sorted(enumerate(sample), key=lambda (n, v): abs(v - pivot))[:k]
Running it with the same elements as before, we get
>>> l = [1,2,3,4]
>>> k_closest(l, 3, 2)
[(2, 3), (1, 2)]
>>> k_closest(l, 3, 3)
[(2, 3), (1, 2), (3, 4)]
For each tuple in the list, the first element is the index in the original array and the second is the number you are actually interested in
If you just want the index, you can tweak the function a bit to become
import operator
def k_closest(sample, pivot, k):
return map(operator.itemgetter(0), sorted(enumerate(sample), key=lambda (n, v): abs(v - pivot)))[:k]
Running with the original input, will now give you
>>> k_closest(l, 3, 2)
[2, 1]
>>> k_closest(l, 3, 3)
[2, 1, 3]
Upvotes: 5
Reputation: 455
You can go through and find the keys corresponding to the closest values. Then append the values corresponding to those keys to a list.
new_array = map(lambda x: abs(x-some_value),my_array)
min_value=min(new_array)
Now find the indices of the new value
my_keys = []
for i,val in enumerate(new_array):
if val == min_value:
my_keys.append(i)
Finally create your output list.
my_answer=[]
for i in my_keys:
my_answer.append(my_array[i])
Upvotes: 0