pnina
pnina

Reputation: 119

Numpy array getting only items and indexes in an ascending order

Suppose I have the following array:

arr = [1,2,4,5,6,5,4,3,2,3,4,5,6,7,8]

I want to get only the items which are in ascending order, and ignore the "reverse" in he middle.

So for this array I want to get: res = [1,2,4,5,6,7,8] ,at the indexes: [0,1,2,4,13,14]

Any idea?

Upvotes: 1

Views: 191

Answers (1)

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 95908

I think you should approach this using the accumulated maximum value, i.e., the maximum value at each given step:

>>> arr
array([1, 2, 4, 5, 6, 5, 4, 3, 2, 3, 4, 5, 6, 7, 8])
>>> np.maximum.accumulate(arr)
array([1, 2, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 8])

You could do something like:

>>> arr[arr == np.maximum.accumulate(arr)]
array([1, 2, 4, 5, 6, 6, 7, 8])

However, that doesn't deal with numbers that stay the same (you get that extra 6), to handle this, you could "roll" the accumulated maximum array and add the condition that it isn't equal to that rolled array (i.e., the value of the array isn't equal to the previous maximum value):

>>> m = np.maximum.accumulate(arr)
>>> arr[(arr == m) & (arr != np.roll(m, -1))]
array([1, 2, 4, 5, 6, 7, 8])

But really, you want the unique values of the accumulated maximum, so you could also just use it with np.unique:

>>> np.unique(np.maximum.accumulate(arr))
array([1, 2, 4, 5, 6, 7, 8])

Not sure which would be faster, but coming up with good testing data isn't straight-forward. If you have a size-able array, I'd be interested in which approach is faster with your data.

Upvotes: 1

Related Questions