3

I have a numpy array:

arr = [0.23, 2.32, 4.04, 5.02, 6.84, 10.12, 10.34, 11.93,12.44]

I want to get the index of the closest integer I enter. For example if I enter 10 then I should get back index 5 (10.12) or if I enter 12 i should get back index 7 (11.93).

1
  • 1
    Is the array guaranteed to be sorted? Commented May 11, 2018 at 20:29

1 Answer 1

2

If your list isn't sorted, you will need a linear time solution using abs + argmin:

>>> np.abs(np.array(arr) - 12).argmin()
7

However, if your list is sorted (ascending or descending), you can employ binary search for a sub-linear time solution (very fast):

# https://ideone.com/aKEpI2 — improved by @user2357112
def binary_search(arr, val):
    # val must be in the closed interval between arr[i-1] and arr[i],
    # unless one of i-1 or i is beyond the bounds of the array.
    i = np.searchsorted(arr, val)

    if i == 0:
        # Smaller than the smallest element
        return i
    elif i == len(arr):
        # Bigger than the biggest element
        return i - 1
    elif val - arr[i - 1] <= arr[i] - val:
        # At least as close to arr[i - 1] as arr[i]
        return i - 1

    # Closer to arr[i] than arr[i - 1]
    return i

cases = [10, 12, 100, 10.12]   # 5, 7, 8, 5
print(*[binary_search(arr, c) for c in cases], sep=',')
Sign up to request clarification or add additional context in comments.

10 Comments

You are a bit sloppy today, aren't you? The searchsorted soln gives the wrong answer for 10 (4 instead of 5).
You have to be a bit more careful with searchsorted if you want the nearest element. Particularly, searching for 0 returns -1, searching for 10.12 fails to report the index of 10.12, and searching for a value between two values of the array always picks the index of the left value, even if the right value is closer.
@PaulPanzer Beg pardon, have been quite sleep deprived of late. Let me fix this, I'll make sure it works.
"have been quite sleep deprived" --- guessed as much ;-)
@PaulPanzer Done, let me know how it shapes up now.
|

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.