滚动中位数比均值更抗异常值,因其仅依赖排序后中间位置的值,单个极值不影响结果;而滚动均值易受噪声污染,适用于监控预处理、iot清洗等场景,但性能较慢且对nan敏感。

滚动中位数为什么比均值更抗异常值
因为中位数不依赖所有值的大小,只看排序后中间位置;单个极大/极小值不会拉偏结果。而 rolling().mean() 会直接被污染,尤其在传感器数据、日志响应时间这类含突发噪声的场景里,平滑后仍残留毛刺。
- 适用场景:监控指标突增检测前的预处理、IoT设备原始读数清洗、金融tick数据去噪
- 注意
rolling().median()默认不支持min_periods小于窗口长度(Pandas ≤ 2.0),若首几个点要补值,得手动用fillna() - 性能上比均值慢约3–5倍(内部需排序),窗口大(如
window=1000)时明显卡顿,建议先采样或用numpy.median手动分块
如何正确设置 rolling().median() 的 window 和 center 参数
窗口大小不是拍脑袋定的:太小去不掉噪声,太大抹平真实变化。常见错误是把 window 设成固定秒数却忽略采样频率不均——比如用 window=5 处理每秒10条的数据,实际覆盖0.5秒,但若某段数据丢包,时间跨度就乱了。
- 时间序列优先用时间偏移:
df['value'].rolling('2S').median()(自动对齐时间索引) - 等间隔数值序列用整数窗口:
df['value'].rolling(window=7).median()(对应7个采样点) -
center=True让输出与原位置对齐(中点对中点),但首尾会多出NaN;center=False(默认)则结果左对齐,首window-1个值为NaN - 若需首尾填充,别用
min_periods=1(它只是降低计算门槛,不解决缺失),应接.fillna(method='bfill').fillna(method='ffill')
rolling().median() 在 NaN 处的行为和修复方式
默认遇到 NaN 就中断计算:哪怕窗口内只有一个 NaN,整个窗口结果就是 NaN。这和 mean() 的 skipna=True 行为不同——median() 没有跳过选项。
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
- 检查原始数据:先跑
df['value'].isna().sum(),确认是否真有缺失而非全零伪装 - 预填充再滚动:用插值(
df['value'].interpolate())或前向填充(df['value'].ffill()),别直接删行(会破坏时间连续性) - 极端情况可改用
scipy.signal.medfilt,它默认忽略边界并支持奇数窗口,但不认 Pandas 时间索引,需转numpy.ndarray
替代方案:当 rolling().median() 不够用时该换什么
滚动中位数本质是局部排序,无法处理趋势漂移或周期性干扰。比如温度数据白天缓慢上升+夜间骤降,单纯中位数会滞后且压扁峰谷。
- 带权重的中位数没有现成实现,但可用
rolling().apply(lambda x: np.average(x, weights=np.ones(len(x))//len(x)))模拟——不推荐,慢且非真正加权中位数 - 更稳的选择是
statsmodels.tsa.seasonal.STL分解 + 中位数滤波残差,适合有明确周期的长序列 - 实时流场景避免
rolling,改用双队列维护滑动窗口,手写中位数更新(用两个堆),否则每次调用都重排太伤
滚动中位数不是万能平滑器,它只解决“局部离群点”,对系统性偏差、采样失真、时钟漂移这些底层问题,再怎么调 window 都没用。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










