4

I have a value, say 2016 and a sorted numpy array: [2005, 2010, 2015, 2020, 2025, 2030]. What is the pythonic way to find the 2 values in the array that bound 2016. In this case, the answer will be an array [2015, 2020].

Not sure how to do it other than loop, but hoping for a more numpy based solution

--EDIT:

you can assume that you will never get a value that is in the array, I prefilter for that

4
  • 1
    Is the array known to be sorted when you start, or could it be in random order? Your example shows a sorted array. Commented Jun 15, 2016 at 0:01
  • yes, the array can be assumed to be sorted Commented Jun 15, 2016 at 0:05
  • What would the correct answer be if the array is the same but the value is 2015? Would it be [2010, 2020], or [2015, 2020], or [2010, 2015], or even just [2015, 2015] ? Commented Jun 15, 2016 at 0:12
  • you can assume that you will never get a value that is in the array, I prefilter for that. Thanks for the question, will update question to reflect this Commented Jun 15, 2016 at 0:13

2 Answers 2

6

A straight-forward approach would be with np.searchsorted -

idx = np.searchsorted(A,B,'left')
out = A[idx],A[idx+1]

Explanation

The inputs are -

In [27]: A
Out[27]: [2005, 2010, 2015, 2020, 2025, 2030]

In [28]: B
Out[28]: 2015

Find the index where B should sit in A to maintain the sorted nature with searchsorted. This would correspond to the lower bound index. So, index into A with index and index+1 for the two bounding values -

In [29]: idx = np.searchsorted(A,B,'left')

In [30]: idx
Out[30]: 2

In [31]: A[idx],A[idx+1]
Out[31]: (2015, 2020)
Sign up to request clarification or add additional context in comments.

1 Comment

This solution is logarithmic (while others take linear time) and should be an accepted answer.
2

You could do something like this:

In[1]: import numpy as np

In[2]: x = np.array([2005, 2010, 2015, 2020, 2025, 2030])

In[3]: x
Out[3]: array([2005, 2010, 2015, 2020, 2025, 2030])


In[4]: x[x > 2016].min()
Out[4]: 2020


In[5]: x[x < 2016].max()
Out[5]: 2015

In[6]: def bound(value, arr):
           return arr[arr < value].max(), arr[arr > value].min()

In[7]: bound(2016, x)
Out[7]: (2015, 2020)

Comments

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.