scipy.signal.

peak_prominences#

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

計算訊號中每個峰值的顯著性。

峰值的顯著性衡量峰值在訊號周圍基線中突出的程度,並定義為峰值與其最低輪廓線之間的垂直距離。

參數:
x序列

帶有峰值的訊號。

peaks序列

x 中峰值的索引。

wlen整數,選用

以樣本為單位的視窗長度,可選擇性地將每個峰值的評估區域限制為 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 四捨五入到下一個奇數整數)。因此,評估區域中僅有的兩個候選者是兩個相鄰的樣本,並且計算出較小的顯著性。