Сделать монохромный массив без контура Python

У меня есть 1D массив значений, который должен быть монотонным (скажем, уменьшающимся), но есть случайные области, где значение увеличивается с индексом.

Мне нужен массив, в котором каждый регион заменяется значением, непосредственно предшествующим ему, так что результирующий массив сортируется.

Итак, если заданный массив:

a = np.array([10.0, 9.5, 8.0, 7.2, 7.8, 8.0, 7.0, 5.0, 3.0, 2.5, 3.0, 2.0])

Я хочу, чтобы результат был

b = np.array([10.0, 9.5, 8.0, 7.2, 7.2, 7.2, 7.0, 5.0, 3.0, 2.5, 2.5, 2.0])

Здесь представлено графическое представление:

example

Я знаю, как добиться этого с помощью цикла Python, но есть ли способ сделать это с помощью оборудования NumPy?

Код Python для ясности:

b = np.array(a)
for i in range(1, b.size):
    if b[i] > b[i-1]:
        b[i] = b[i-1]

Ответ 1

Вы можете использовать np.minimum.accumulate для сбора минимальных значений при перемещении по массиву:

>>> np.minimum.accumulate(a)
array([ 10. ,   9.5,   8. ,   7.2,   7.2,   7.2,   7. ,   5. ,   3. ,
         2.5,   2.5,   2. ])

В каждом элементе массива эта функция возвращает минимальное значение, полученное до сих пор.

Если вы хотите, чтобы массив был монотонным, вы можете использовать np.maximum.accumulate.

Многие другие универсальные функции в NumPy имеют метод accumulate для имитации цикла по массиву, применения функции к каждому элементу и сбора возвращаемые значения в массив того же размера.