argrelextrema и плоские экстремумы

функция argrelextrema от scipy.сигнал не обнаруживает плоские экстремумы. Пример:

import numpy as np
from scipy.signal import argrelextrema
data = np.array([ 0, 1, 2, 1, 0, 1, 3, 3, 1, 0 ])
argrelextrema(data, np.greater)
(array([2]),)

первый max (2) обнаружен, второй max (3, 3) не обнаружен.

любое обходное решение для этого поведения? Спасибо.

1 ответов


короткий ответ: наверное argrelextrema не будет достаточно гибким для вашей задачи. Подумайте о том, чтобы написать свою собственную функцию, соответствующую вашим потребностям.


более длинный ответ: вы обязаны использовать argrelextrema? Если да, то вы можете поиграть с comparator и order доводы argrelextrema (см. ссылка).

для вашего простого примера, было бы достаточно выбрать np.greater_equal as comparator.

>>> data = np.array([ 0, 1, 2, 1, 0, 1, 3, 3, 1, 0 ])
>>> print(argrelextrema(data, np.greater_equal,order=1))
(array([2, 6, 7]),)

обратите внимание, однако, что таким образом

>>> data = np.array([ 0, 1, 2, 1, 0, 1, 3, 3, 4, 1, 0 ])
>>> print(argrelextrema(data, np.greater_equal,order=1))
(array([2, 6, 8]),)

ведет себя по-другому, что вы, вероятно, хотели бы, найти первый 3 и 4 как Максима, так как argrelextrema теперь видит все как максимум, который больше или равен двум его ближайшим соседям. Теперь вы можете использовать order аргумент, чтобы решить, сколько соседей это сравнение должно держать-выбор order=2 изменил бы мой верхний пример, чтобы найти только 4 как максимальный.

>>> print(argrelextrema(data, np.greater_equal,order=2))
(array([2, 8]),)

есть, однако, обратная сторона этого-давайте изменим данные еще раз:

>>> data = np.array([ 0, 1, 2, 1, 0, 1, 3, 3, 4, 1, 5 ])
>>> print(argrelextrema(data, np.greater_equal,order=2))
(array([ 2, 10]),)

добавление еще одного пика в качестве последнего значения не дает вам найти свой пик в 4, as argrelextrema теперь видит второго соседа, который больше, чем 4 (что может быть полезно для шумных данных, но не обязательно поведение, ожидаемое во всех случаях).


используя argrelextrema, вы всегда будете ограничены бинарными операциями между a фиксированное количество соседей. Заметьте, однако, что все argrelextrema в вашем примере выше-вернуть n, если data[n] > data[n-1] and data[n] > data[n+1]. Вы можете легко реализовать это самостоятельно, а затем уточнить правила, например, проверив второй сосед в случае, если первый сосед имеет то же значение.


для полноты, кажется, есть более сложная функция в scipy.signal, find_peaks_cwt. Однако у меня нет опыта его использования, и поэтому я могу не буду вдаваться в подробности.