argrelextrema和扁平极


问题内容

来自scipy.signal的函数argrelextrema无法检测到平坦的极值。例:

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]),)

第一个最大值(2)被检测到,第二个最大值(3,3)没有被检测到。

此行为有任何解决方法吗?谢谢。


问题答案:

简短的答案: 可能argrelextrema不够灵活。考虑编写符合您需要的函数。


更长的答案:
您一定要使用argrelextrema吗?如果是,则可以使用comparator和的order参数argrelextrema(请参阅参考资料)。

对于您的简单示例,选择np.greater_equalas就足够了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]),)

找到第一个34最大的行为,可能会表现出与您可能想要的不同的方式,因为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,因为argrelextrema现在看到的第二个邻居大于4(对于嘈杂的数据很有用,但不一定在所有情况下都具有预期的行为)。


使用argrelextrema,您将始终被限制在固定数量的邻居之间进行二进制操作。但是请注意,argrelextrema以上示例中的所有操作都是n如果返回`data[n]

data[n-1] and data[n] >
data[n+1]`。您可以轻松地自己实现,然后完善规则,例如在第一个邻居具有相同值的情况下检查第二个邻居。


为了完整起见,似乎有更复杂的功能scipy.signalfind_peaks_cwt。但是,我没有使用它的经验,因此无法为您提供更多详细信息。