缺失值处理:向前填充、向后填充、插值法、删除策略——什么时候该用哪个?

做量化数据清洗这些年,我遇到最多的坑就是缺失值。说实话,刚入行那会儿我总觉得缺失值处理很简单——删掉不就完了?直到有一次,因为错误地删除了关键时间点的缺失数据,导致回测结果完全失真,差点让一个策略模型报废。

今天咱们就来聊聊,面对缺失值,到底该怎么选。

先搞清楚缺失值的类型

动手处理之前,我习惯先问自己一个问题:这个缺失值是怎么产生的?

一般来说,行情数据的缺失分三种情况:

  • 完全随机缺失:比如网络抖动丢了一个 tick,这种最省心
  • 随机缺失:比如某些流动性差的股票,下午三点后就没成交了
  • 非随机缺失:比如熔断期间所有数据都停了,这种最麻烦

你想想看,如果搞不清缺失原因就直接套方法,很容易出问题。我在项目中就吃过这个亏——有一次把停牌期间的数据用向前填充补上了,结果策略在复牌那天疯狂交易,亏得一塌糊涂。

向前填充(Forward Fill)

向前填充,说白了就是用上一个有效值来填补当前缺失。这是我最常用的方法,尤其是在处理高频行情时。

适用场景:

  • 价格数据:比如股票在非交易时段,价格应该沿用上一笔成交价
  • 订单簿数据:买卖盘口没有变化时,用前一个状态是合理的
  • 低频采样数据:比如5分钟K线,中间缺失的1分钟数据可以向前填充
# 向前填充示例
import pandas as pd

df['close'].fillna(method='ffill', inplace=True)

嗯,这里要注意:向前填充有个隐含假设——数据变化是缓慢的。如果市场剧烈波动,这个方法就不太靠谱了。我记得有一次处理比特币的秒级数据,价格在几秒内波动了5%,向前填充的结果直接让策略信号延迟了。

向后填充(Backward Fill)

向后填充和向前填充正好相反,用下一个有效值来填补当前缺失。这个方法我用得相对少一些,但在某些场景下特别好使。

我个人习惯:向后填充更适合处理「已知未来值」的场景。比如你要计算某个时间点的指标,但数据是延迟到达的,用向后填充可以提前占位。

# 向后填充示例
df['volume'].fillna(method='bfill', inplace=True)

举个例子:交易所的成交量数据有时会延迟几秒才推送。如果你在做实时策略,用向后填充可以保证数据对齐。但要注意——这相当于「偷看未来」,回测时千万别这么干,否则结果会虚高。

插值法(Interpolation)

插值法就灵活多了。它不是简单地复制上一个值,而是根据数据趋势来估算缺失值。我一般把它当作「高级版填充」来用。

插值方法 适用场景 我的经验
线性插值 价格走势平稳时 最常用,简单有效
多项式插值 数据有曲线趋势时 小心过拟合,我吃过亏
时间插值 时间间隔不均匀时 处理期货数据时必用
# 线性插值示例
df['close'].interpolate(method='linear', inplace=True)

# 时间插值(按时间权重)
df['close'].interpolate(method='time', inplace=True)

为什么会推荐时间插值?因为行情数据的时间戳往往不是均匀的。比如某只股票在开盘前5分钟成交密集,之后变得稀疏。用时间插值能更好地反映真实的市场节奏。

我曾经踩过的坑:用高阶多项式插值处理分钟级数据,结果在拐点处出现了「龙摆尾」现象——插出来的值比实际最高价还高。后来我学乖了,除非数据本身有明显的非线性特征,否则尽量用线性插值。

删除策略(Drop)

删除是最简单粗暴的方法,但也是最容易出问题的。我现在的原则是:能不删就不删,除非万不得已。

什么情况下该删?

  • 缺失比例极小(比如不到1%),删了不影响统计
  • 缺失值集中在某个时间段,且该时间段对策略无意义
  • 数据量极大,删除后仍有足够样本
# 删除缺失值
df.dropna(inplace=True)

# 只删除缺失比例超过50%的列
df.dropna(thresh=len(df)*0.5, axis=1, inplace=True)

但要注意:千万别在回测中随意删除数据。你删掉的那一行,可能正好是某个关键信号出现的时间点。我见过有人删了5%的缺失数据,结果夏普比率从1.2变成了2.0——这明显是数据挖掘偏差。

到底该怎么选?一张图说清楚

说了这么多,你可能有点晕。我画了一张流程图,帮你快速决策:

缺失值处理决策流程 发现缺失值 缺失比例 < 1%? 直接删除 价格类数据? 向前填充 有明显趋势? 插值法 向后填充

实战中的选择逻辑

说了这么多理论,来点实际的。我一般按这个顺序决策:

  1. 先看缺失比例:如果不到1%,直接删,省事
  2. 再看数据类型:价格类数据用向前填充,成交量类数据用插值
  3. 最后看趋势:有明显趋势的用插值,没有趋势的用向后填充

一个小技巧:如果你不确定该用哪种方法,可以做个「敏感性分析」——分别用不同方法处理,看看对最终策略的影响有多大。我一般会跑三个版本:向前填充、插值、删除,然后对比结果。如果差异很小,说明缺失值影响不大;如果差异很大,那就要仔细检查数据源了。

避坑指南

最后,分享几个我踩过的坑:

  • 别在回测中混合使用不同方法:比如训练集用插值,测试集用向前填充,结果会失真
  • 注意边界情况:数据开头和结尾的缺失值,向前/向后填充都无效,这时候只能删或插值
  • 多市场数据要分开处理:A股和美股的数据特征不同,别用同一套参数

嗯,关于缺失值处理,今天就聊到这儿。记住一句话:没有最好的方法,只有最合适的方法。多试、多对比,慢慢你就有感觉了。

专注资料整理