20

I have this numpy array where the values in each row will always be sorted and monotonically increasing:

a = np.array([[1, 2, 3, 4, 8],
       [2, 5, 6, 7, 8],
       [5, 7, 11, 12, 13]])

and I want to search for the following values (which are NOT sorted or monotonic) for each row:

b = np.array([4.5, 2.3, 11.6])

so that I get an answer of:

[4, 1, 3]

However, searchsorted does not support this (it feels like it needs an axis keyword).

Is there an EFFICIENT way I can do this for a very large array? Obviously with a for loop I can index the array a and b like this:

for i in np.arange(np.alen(a)):
     print a[i].searchsorted(b[i])

but this is slow when a is large.

Is there a way to do this in numpy that is more efficient?

1
  • 1
    why the negative score on this question? Commented Mar 26, 2014 at 8:52

1 Answer 1

2

You can searchsorted on the ravel/flattened array:

In [11]: np.searchsorted(a.ravel(), b)
Out[11]: array([3, 6])

You can then use divmod on the result (which gets the row and column):

In [12]: divmod(np.searchsorted(a.ravel(), b), a.shape[1])
Out[12]: (array([0, 1]), array([3, 1]))
Sign up to request clarification or add additional context in comments.

7 Comments

That requires that every row has larger values then any preceding row, which is the case of the OP's example, but seems a strong condition for general arrays.
@Andy - an elegant solution to the example in the question, but, as Jamie says, it does not work for cases where b is not monotonically ascending. I have updated the question so it is more clear. Thanks.
@KernowBunney ah, ok so something more efficient but similar to np.diag(np.apply_along_axis(np.searchsorted, 1, a, b)). Dropping to cython is an easy option for perf of your for loop.
@Andy Hayden - thanks for that - apply_along_axis works and is at least more succinct/Numpy-like than a Python loop. I will investigte Cython. Cheers!
@GoingMyWay. apply_along_axis is a glorified python level for loop under the hood, just like vectorize
|

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.