<p>函数<a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html" rel="noreferrer">^{<cd1>}</a>,顾名思义,对此很有用。但了解其参数<code>width</code>、<code>threshold</code>、<code>distance</code><strong>以及最重要的参数<code>prominence</code></strong>是获得良好峰提取的重要条件。</p>
<p>根据我的测试和文档,突出度的概念是“有用的概念”,它可以保留好的峰值,并丢弃有噪声的峰值。</p>
<p>什么是<a href="https://en.wikipedia.org/wiki/Topographic_prominence" rel="noreferrer">(topographic) prominence</a>?它是从山顶到任何更高地形所需的最低下降高度,如图所示:</p>
<p><a href="https://i.stack.imgur.com/c2xE7.png" rel="noreferrer"><img src="https://i.stack.imgur.com/c2xE7.png" alt="enter image description here"/></a></p>
<p>想法是:</p>
<blockquote>
<p>The higher the prominence, the more "important" the peak is.</p>
</blockquote>
<p>测试:</p>
<p><a href="https://i.stack.imgur.com/zFU2l.png" rel="noreferrer"><img src="https://i.stack.imgur.com/zFU2l.png" alt="enter image description here"/></a></p>
<p>我特意用了一个(有噪声的)频率变化的正弦波,因为它显示出许多困难。我们可以看到,<code>width</code>参数在这里不是很有用,因为如果设置的最小值<code>width</code>太高,那么它将无法跟踪高频部分非常接近的峰值。如果将<code>width</code>设置得太低,则信号左侧会出现许多不需要的峰值。与<code>distance</code>相同的问题。<code>threshold</code>只与直接邻居进行比较,这在这里是不有用的。<code>prominence</code>是最好的解决方案。请注意,您可以组合这些参数中的许多!</p>
<p>代码:</p>
<pre><code>import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import find_peaks
x = np.sin(2*np.pi*(2**np.linspace(2,10,1000))*np.arange(1000)/48000) + np.random.normal(0, 1, 1000) * 0.15
peaks, _ = find_peaks(x, distance=20)
peaks2, _ = find_peaks(x, prominence=1) # BEST!
peaks3, _ = find_peaks(x, width=20)
peaks4, _ = find_peaks(x, threshold=0.4) # Required vertical distance to its direct neighbouring samples, pretty useless
plt.subplot(2, 2, 1)
plt.plot(peaks, x[peaks], "xr"); plt.plot(x); plt.legend(['distance'])
plt.subplot(2, 2, 2)
plt.plot(peaks2, x[peaks2], "ob"); plt.plot(x); plt.legend(['prominence'])
plt.subplot(2, 2, 3)
plt.plot(peaks3, x[peaks3], "vg"); plt.plot(x); plt.legend(['width'])
plt.subplot(2, 2, 4)
plt.plot(peaks4, x[peaks4], "xk"); plt.plot(x); plt.legend(['threshold'])
plt.show()
</code></pre>