4

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.

6
  • the issue is that you are trying to find the nearest item, but multiple times, so how many do you want? because if for example, every time we find the nearest we remove it from the list, then we can continue, and so on, but one must set a limit, otherwise one would end up with all the values at the end.... Commented Apr 13, 2016 at 21:13
  • for the duplicates, it's simple, it's the index of all the values equal to the nearest just found, and so on. Commented Apr 13, 2016 at 21:14
  • You're looking for the n closest numbers, or all numbers within an interval [x-d, x+d]? Commented Apr 13, 2016 at 21:20
  • Given an array of values, find all the values from an array closest to a user given number. For all the close values the code finds, return those indices. Commented Apr 14, 2016 at 23:33
  • 1
    @WXNerd Does "closest" mean literally "the closest" or maybe "within some tolerance interval"? Judging on the values you provided, it may be the latter. Commented Apr 15, 2016 at 4:25

3 Answers 3

5

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]
Sign up to request clarification or add additional context in comments.

Comments

0

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

2 Comments

I am getting an error message in the first line when I try to run this code. I put in the name of my array in my_array and the number that I am looking for in some_value. I am getting the message: 'TypeError: map() requires at least two args'. I do not see how an argument is missing.
Should be fixed. You'll have to replace the variable names with your variables.
0

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?

2 Comments

The numbers at indices 7 and 10 are correct from my data.
Updated my answer with one by one comparison for those elements. Feel free to clarify if something is missing..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.