Let's say I have an array:
a = [1,4,3,6,4]
I want to get an array where for every element I have the smallest value in a
to the right (inclusive). That is, for a
, I would want to create an array:
[1,3,3,4,4]
Is there a quick, concise way to do this?
You question is actually ambiguous. Do you want to consider the following value or all following values?
compute a cumulated minimum on the reversed array with minimum.accumulate
:
a = np.array([1,4,3,6,4])
out = np.minimum.accumulate(a[::-1])[::-1]
Output:
array([1, 3, 3, 4, 4])
With pure python and itertools.accumulate
:
from itertools import accumulate
a = [1,4,3,6,4]
out = list(accumulate(a[::-1], min))[::-1]
# [1, 3, 3, 4, 4]
You could shift the values and use np.minimum
:
a = np.array([1,4,3,6,4])
out = np.minimum(a, np.r_[a[1:], a[-1]])
Output:
array([1, 3, 3, 4, 4])
or compare the successive values and build a mask to modify a
in place:
a = np.array([1,4,3,6,4])
m = a[:-1] > a[1:]
# or
# m = np.diff(a) < 0
a[np.r_[m, False]] = a[1:][m]
Modified a
:
array([1, 3, 3, 4, 4])
a = np.array([1,4,3,6,5,6,4])
np.minimum.accumulate(a[::-1])[::-1]
# array([1, 3, 3, 4, 4, 4, 4])
np.minimum(a, np.r_[a[1:], a[-1]])
# array([1, 3, 3, 5, 5, 4, 4])