scipy 弧极值与平坦极值

5sxhfpxr  于 2022-11-09  发布在  其他
关注(0)|答案(2)|浏览(174)

scipy.信号中的函数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)。
对于这种行为有什么解决办法吗?谢谢。

ibrsph3r

ibrsph3r1#

简短回答:argrelextrema可能不够灵活,无法满足您的任务。请考虑编写符合您需要的函数。
**更长的答案:**您一定要使用argrelextrema吗?如果是的话,那么您可以使用argrelextremacomparatororder参数(请参阅reference)。

对于您的简单示例,选择np.greater_equal作为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=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,if data[n] > data[n-1] and data[n] > data[n+1]。您可以自己轻松地实现这一点,然后细化规则,例如,通过检查第二个邻居,以防第一个邻居具有相同的值。
为了完整起见,scipy.signal中似乎有一个更复杂的函数find_peaks_cwt。但是我没有使用它的经验,因此不能给予你更多的细节。

5tmbdcev

5tmbdcev2#

我真的很惊讶没有人能找到答案。你所需要做的就是对数组进行预处理,删除相邻的重复项,然后运行argrelextrema,如下所示:

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

filter_table = [False] + list(np.equal(data[:-1], data[1:]))
data = np.array([x for idx, x in enumerate(data) if not filter_table[idx]])
argrelextrema(data, np.greater)

相关问题