scipy.signal.

peak_prominences#

scipy.signal.peak_prominences(x, peaks, wlen=None)[source]#

计算信号中每个峰的突出度。

峰的突出度测量了峰在信号周围基线中凸出的程度,其定义为峰与其最低等值线之间的垂直距离。

参数:
x序列

具有峰的信号。

peaks序列

x 中峰的索引。

wlenint,可选

样本的窗口长度,可选,将每个峰的评估区域限制为 x 的子集。峰始终放置在窗口的中间,因此给定的长度向上舍入到下一个奇数。此参数可以加快计算速度(请参阅注释)。

返回:
prominencesndarray

peaks 中每个峰的计算突出度。

left_bases, right_basesndarray

峰的基作为每个峰左右 x 中的索引。每对中较高的基是峰的最低等值线。

引发:
ValueError

如果 peaks 中的值对于 x 来说是一个无效索引。

警告:
PeakPropertyWarning

对于 peaks 中指向 x 中的无效局部最大值的索引,所返回的显著性将为 0,并会发出此警告。如果 wlen 小于峰的高原大小,也会发生这种情况。

警告

对于包含 NaN 的数据,此函数可能会返回意外结果。为了避免这种情况,NaN 应该被移除或替换。

另请参见

find_peaks

基于峰值属性在信号内查找峰值。

peak_widths

计算峰值的宽度。

注意

计算峰值显著性的策略

  1. 从当前峰向左右水平延伸一条线,直到该线到达窗口边框(参见 wlen)或在更高峰的斜坡处再次与信号相交。忽略与同等高度峰值的相交。

  2. 在上面定义的间隔内,找到每侧的最小信号值。这些点是峰值基点。

  3. 两个基点中较高的一个标记峰值的最低等高线。然后可以将显著性计算为峰值高度本身与其最低等高线之间的垂直差异。

对于带有周期性行为的大 x,搜索峰值基点可能是缓慢的,因为第一个算法步骤需要针对大型区块甚至整个信号进行评估。这个评估区域可以用 wlen 参数来限制,它将算法限制在当前峰周围的一个窗口中,并且如果窗口长度相对于 x 较短,可以缩短计算时间。但是,如果峰值的真实基点超出此窗口,这可能会阻止算法找到真正的全局等高线。相反,将找到受限窗口内的较高等高线,从而导致计算出的显著性较小。在实践中,这仅与 x 中最高组峰值相关。甚至可以有意识地使用这种行为来计算“局部”显著性。

在版本 1.1.0 中添加。

参考

[1]

地形显著性的维基百科文章:https://en.wikipedia.org/wiki/Topographic_prominence

示例

>>> import numpy as np
>>> from scipy.signal import find_peaks, peak_prominences
>>> import matplotlib.pyplot as plt

使用两个重叠谐波创建测试信号

>>> x = np.linspace(0, 6 * np.pi, 1000)
>>> x = np.sin(x) + 0.6 * np.sin(2.6 * x)

查找所有峰值并计算显著性

>>> peaks, _ = find_peaks(x)
>>> prominences = peak_prominences(x, peaks)[0]
>>> prominences
array([1.24159486, 0.47840168, 0.28470524, 3.10716793, 0.284603  ,
       0.47822491, 2.48340261, 0.47822491])

计算每个峰值等高线的高度并绘制结果

>>> contour_heights = x[peaks] - prominences
>>> plt.plot(x)
>>> plt.plot(peaks, x[peaks], "x")
>>> plt.vlines(x=peaks, ymin=contour_heights, ymax=x[peaks])
>>> plt.show()
../../_images/scipy-signal-peak_prominences-1_00_00.png

我们来评估第二个示例,该示例说明了索引为 5 的一个峰值的几个临界情况。

>>> x = np.array([0, 1, 0, 3, 1, 3, 0, 4, 0])
>>> peaks = np.array([5])
>>> plt.plot(x)
>>> plt.plot(peaks, x[peaks], "x")
>>> plt.show()
../../_images/scipy-signal-peak_prominences-1_01_00.png
>>> peak_prominences(x, peaks)  # -> (prominences, left_bases, right_bases)
(array([3.]), array([2]), array([6]))

请注意,在寻找左边界时,高度相同的索引 3 处峰值不被视为边界。相反,在 0 和 2 处找到两个最小值,在这种情况下,始终选择更接近评估峰值的一个。然而,在右侧,必须将边界放置在 6 上,因为较高的峰值表示评估区域的右边界。

>>> peak_prominences(x, peaks, wlen=3.1)
(array([2.]), array([4]), array([6]))

这里,我们将算法限制为 3 到 7 之间的一个窗口(长度为 5 个样本,因为 wlen 被舍入到下一个奇数整数)。因此,评估区域中的唯一两个候选项是两个相邻样本,并且计算了较小的突出度。