scipy.signal.find_peaks
その名前が示すように、関数はこれに役立ちます。しかし、それはよくそのパラメータを理解することが重要だwidth
、threshold
、distance
そして何よりもprominence
良好なピーク抽出を取得します。
私のテストとドキュメントによると、卓越性の概念は、良好なピークを維持し、ノイズの多いピークを破棄するための「有用な概念」です。
(地形)目立ちとは何ですか?それは、「任意の高い地形に頂上から取得するために下降するために必要な最小の高さ」、それはここで見られるように、:
アイデアは:
目立つほど、ピークはより「重要」になります。
テスト:
(ノイズの多い)周波数が変化する正弦波を意図的に使用しました。width
最小値をwidth
高く設定しすぎると、高周波部分の非常に近いピークを追跡できなくなるため、このパラメーターはあまり役に立たないことがわかります。width
低く設定しすぎると、信号の左側に不要なピークが多数発生します。と同じ問題distance
。threshold
ここでは役に立ちませんが、直接隣人と比較するだけです。prominence
最高のソリューションを提供するものです。これらのパラメータの多くを組み合わせることができることに注意してください!
コード:
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()