You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SciPy调用find_peaks检测时序数据频率时误检多峰值问题求解

问题描述

我有一个包含数十万个(time, value)采样点的数据文件,希望基于这些数据点估算对应波形的频率。我原本尝试使用SciPy的find_peaks函数,为每个真实峰值匹配单个采样点,通过计算相邻峰值的平均时间间隔求解频率,但实际调用find_peaks函数时,单个真实峰值被误识别为多个峰值,检测全局效果如下图所示:
峰值检测全局效果
单个峰值的局部放大效果如下:
单峰局部放大效果

我尝试通过设置prominence参数过滤噪声导致的假峰值,但始终未达到预期过滤效果,相关实现代码如下:

peak_idxs = list(
    sig.find_peaks(
        data,
        prominence=0.15,
        width=(0, 0.05 * sample_freq),
    )[0]
)
troph_idxs = list(
    sig.find_peaks(
        np.negative(data),
        prominence=0.15,
        width=(0, 0.05 * sample_freq),
    )[0]
)
peak_criticals = [timestamps[i] for i in peak_idxs]
troph_criticals = [timestamps[i] for i in troph_idxs]
t_criticals_freqs = [
    1 / (b - a) for a, b in zip(peak_criticals[0:], peak_criticals[1:])
] + [1 / (b - a) for a, b in zip(troph_criticals[0:], troph_criticals[1:])]

freq = statistics.mean(t_criticals_freqs)

ax.plot(timestamps, data)
ax.plot(
    [timestamps[i] for i in peak_idxs + troph_idxs],
    [data[i] for i in peak_idxs + troph_idxs],
    "r*",
)

需要调整参数或检测方案,实现准确识别真实波峰波谷、正确计算时序波形频率的目标。

解决方案

单峰被误识别为多个峰值的核心原因是信号叠加了高频噪声,峰值顶部的小幅抖动被find_peaks判定为独立峰值,单纯调整prominence和width参数很容易在滤除假峰的同时漏掉真实峰值,可按以下方案调整:

  • 检测前增加信号平滑预处理:在峰值检测前对原始信号做低通滤波或者滑动平均平滑,消除峰值顶部的高频毛刺。如果不想引入相位偏移,优先使用scipy.signal.medfilt中值滤波,窗口大小设为采样率下1~2个噪声抖动周期的长度,通常取int(0.005*sample_freq)到int(0.01*sample_freq)的奇数即可,既可以磨平尖峰噪声,又不会明显改变真实峰值的位置。
  • 给find_peaks增加distance参数:该参数会强制两个检测到的峰值之间的最小采样点间隔,直接从规则层面避免同一个宽峰顶部的多个抖动被重复识别。参数值按信号的最小预估周期设置即可,比如估算信号基频在f0附近,就设distance=int(0.8/f0 * sample_freq),保证同一个真实峰范围内只会保留幅值最高的一个峰值点,波谷检测可复用同样的参数逻辑。
  • 增加检测后峰值合并逻辑:如果不想对原始信号做平滑处理,可以在峰值检测完成后做一次聚类合并:把时间间隔小于预设最小峰间距的峰值归为同一组,每组只保留幅值最大的点作为真实峰值,波谷检测用相同逻辑处理即可。
  • 频率稳定场景可换用FFT计算:如果被测信号的频率整体比较稳定,不需要追踪局部瞬时频率,可以直接对信号做快速傅里叶变换,取幅值最大的频率分量作为结果,该方法抗噪性远高于峰值间隔法,针对数十万采样点的计算速度也非常快。

注意:使用滤波预处理时不要把窗口设置过大,否则会磨平真实波形特征,导致峰值位置偏移,最终引入频率计算误差。


内容的提问来源于stack exchange,提问作者Jeff L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 17:09:25