Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy searchsorted descending order

I am trying to understand how to correctly use numpy.searchsorted to find the correct index where to insert an element. When i run the following:

e = np.array([9,8,7,6])
np.searchsorted(e,5)

The output I get is 0, which is wrong as I would expect 4 as the answer. Is searchsorted usable for arrays ordered in descending order? What options do I have if I need to keep the array in descending order? Thanks a lot!

like image 724
pellungrobe Avatar asked Mar 29 '17 14:03

pellungrobe


3 Answers

As is described in the documentation:

numpy.searchsorted(a, v, side='left', sorter=None)

Find indices where elements should be inserted to maintain order.

Find the indices into a sorted array a such that, if the corresponding elements in v were inserted before the indices, the order of a would be preserved.

Parameters:

  • a : 1-D array_like

    Input array. If sorter is None, then it must be sorted in ascending order, otherwise sorter must be an array of indices that sort it.

(...)

(formatting added)

So you have to provide an array sorted in ascending order.

Nevertheless it is easy to solve this issue for numerical data: you simply use the negation:

e = np.array([9,8,7,6])
np.searchsorted(-e,-5)
#               ^  ^

You can also use the reversed array (for instance for non-numerical data) as is proposed by @Psidom.

like image 57
Willem Van Onsem Avatar answered Nov 15 '22 06:11

Willem Van Onsem


You can search the reversed array, and then reverse the index later:

e = np.array([9,8,7,6])
e.size - np.searchsorted(e[::-1], 5, side = "right")
# 4

Notice the side parameter here needs to be opposite to directly search the original array if you want the result to be consistent.

like image 27
Psidom Avatar answered Nov 15 '22 08:11

Psidom


You can do it using the sorter optional argument. As per the documentation this is usually the result of np.argsort(e):

array([3, 2, 1, 0])

Which you can produce more efficiently this way:

np.arange(len(e)-1, -1, -1)

Then:

np.searchsorted(e, 7.5, sorter=np.arange(len(e)-1, -1, -1))

Gives you 2.

like image 39
John Zwinck Avatar answered Nov 15 '22 08:11

John Zwinck