savgol_filter处理长数据数组时输出为nan的问题咨询
核心入参含义
首先明确你代码中savgol_filter用到的参数对应作用:
- 首位参数:待平滑的输入数组
- 第二个参数
window_length=81:滑动计算的窗口长度,必须为正奇数,且要求窗口长度 > 多项式拟合阶数,数值越大平滑力度越强,同时会抹除更多原始数据的细节特征 - 第三个参数
polyorder=3:窗口内数据拟合的多项式阶数,数值越高越容易保留原始数据的波动,拟合精度越高但也更容易出现过拟合 - 第四个参数
delta=0.5:采样点间隔,仅在设置deriv参数(求导阶数)不为0时生效,你当前没有配置求导需求,该参数不影响平滑结果
输出nan的故障原因
长数组场景下偶发nan,基本属于以下三类问题:
- 输入数组存在连续的完全相同的数值片段,窗口滑动到该区域时,三阶多项式拟合的协方差矩阵会出现奇异,无法求逆得到拟合系数,最终输出nan
- 使用的scipy版本低于1.2.0,旧版本的边界外推逻辑存在缺陷,当边界附近数值极差超过1e6量级时,计算会出现数值溢出,被自动标记为nan
- 输入数组为低精度整型(如uint8、int16),窗口内求和计算时出现溢出,后续计算得到无效值
解决方案
按优先级从高到低尝试即可:
- 优先升级scipy到1.7.0及以上稳定版本,旧版本的数值溢出、边界计算缺陷已经得到官方修复
- 新增
mode参数指定边界处理规则,避免边界外推异常,推荐设置为mode='nearest',修改后代码如下:SmoothMeasurement = savgol_filter(Measurement, 81, 3, delta=0.5, mode='nearest') - 如果输入数组存在大量连续恒值段,可先对数组加入极小幅值的高斯噪声(噪声幅值比数据精度小1个量级即可),再进行平滑处理,避免奇异矩阵问题
- 若以上方案都无效,可适当调小窗口长度(调整后仍需保证为奇数),降低拟合时出现数值问题的概率
内容的提问来源于stack exchange,提问作者Karol Peters
相关产品推荐
相关产品推荐

