如何在Python中提升使用Scipy查找局部极大值、极小值的准确度?
以下是提升Scipy局部极值检测准确度的可落地方法:
- 调整邻域比较范围
order参数
默认order=1仅对比当前点左右各1个点,放大该值(比如设为3、5),要求当前点比左右连续N个点都大/小时才判定为极值,可大幅过滤小幅噪声导致的假极值,示例代码:# 要求当前点比左右各3个点都大才判定为极大值 argrelextrema(z, np.greater, order=3) - 先对原始数据做平滑预处理
原始数据存在高频噪声时,会生成大量无意义的假极值,先使用滤波算法降噪后再做检测,常用平滑方法有Savitzky-Golay滤波、滑动平均滤波,示例代码:from scipy.signal import savgol_filter # 窗口长度5、2次多项式拟合做平滑,窗口长度需设为奇数 z_smoothed = savgol_filter(z, window_length=5, polyorder=2) # 用平滑后的数据检测极值 argrelextrema(z_smoothed, np.greater, order=2) - 增加极值幅值阈值过滤
拿到检测结果后,筛掉幅值不符合要求的点,比如要求极大值不低于全局最大值的30%,极小值不高于全局最小值的120%,过滤掉小幅波动的误判:import numpy as np max_idx = argrelextrema(z, np.greater, order=3)[0] # 保留幅值大于全局最大值30%的真实极大值 valid_max_idx = max_idx[z[max_idx] >= 0.3 * np.max(z)] - 替换为功能更完善的专用峰检测API
针对单维序列的极值/峰检测,scipy.signal.find_peaks的实用性远高于通用的argrelextrema,可直接配置高度阈值、相邻峰最小距离、峰突出度、峰宽等参数,适配大部分场景需求,示例代码:from scipy.signal import find_peaks # 要求峰高≥0.5,相邻峰最小间距为5个点,峰比两侧低谷至少高0.3 peaks, properties = find_peaks(z, height=0.5, distance=5, prominence=0.3) - 适配边界处理规则
如果数据首尾区域的极值存在漏判/误判,可以调整mode参数适配边界逻辑,可选值有clip(边界值外推为同值)、wrap(循环边界)、nearest(取最近的点做对比)。
内容的提问来源于stack exchange,提问作者tangerine0803
相关产品推荐
相关产品推荐

