scipy.signal.

peak_prominences#

scipy.signal.peak_prominences(x, peaks, wlen=None)[源代码]#

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

峰的突出度衡量一个峰在信号周围基线上的突出程度,定义为峰与其最低等高线之间的垂直距离。

参数:
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 向上舍入到下一个奇数整数)。 因此,评估区域中仅有的两个候选者是两个相邻样本,并且计算出的突出度较小。