2. 处理缺失的收盘价数据
任务说明
本案例处理一份包含股票代码、交易日期和收盘价的历史行情数据,其中收盘价字段存在缺失值。目标是对缺失的收盘价进行识别,并采用前向填充(ffill)或线性插值(linear interpolation)两种方法完成填补,最终输出处理后的完整数据集,并对比两种方法的差异。
数据准备
为便于独立复现,直接构造一份包含缺失值的样例数据。数据共10个交易日,股票代码为000001.SZ,其中第3、第6、第8天的收盘价缺失。
import pandas as pd
import numpy as np
# 构造含缺失收盘价的样例数据
df = pd.DataFrame({
'ts_code': ['000001.SZ'] * 10,
'trade_date': pd.date_range('2024-01-02', periods=10, freq='D'),
'close': [10.5, 10.8, np.nan, 11.2, 11.0, np.nan, 11.5, np.nan, 11.8, 12.0]
})
print("原始数据:")
print(df)
print("\n缺失值数量:", df['close'].isna().sum())
缺失值识别与处理
首先识别缺失值位置,然后分别用前向填充和线性插值生成两个新列,最后对比结果。
# 识别缺失位置
missing_mask = df['close'].isna()
print("缺失值所在行索引:", df.index[missing_mask].tolist())
# 方法一:前向填充(用上一个有效值填充)
df['close_ffill'] = df['close'].ffill()
# 方法二:线性插值(按索引等距插值)
df['close_interp'] = df['close'].interpolate(method='linear')
# 查看处理结果
print("\n处理后的数据:")
print(df[['trade_date', 'close', 'close_ffill', 'close_interp']])
结果对比与判定
前向填充将缺失值替换为最近的前一个有效收盘价;线性插值则根据缺失值前后两个有效值按时间等距计算中间值。两种方法填补后的数据均可直接用于后续计算收益率或技术指标。判定处理成功的标准为:close_ffill和close_interp两列均无缺失值,且close_ffill中第3天值为10.8(取自第2天),close_interp中第3天值为11.0(10.8与11.2的均值)。
# 验证:处理后无缺失
assert df['close_ffill'].notna().all(), "前向填充仍有缺失"
assert df['close_interp'].notna().all(), "插值仍有缺失"
print("\n验证通过:两种方法均已完成缺失值填补,无剩余缺失。")
print("前向填充第3天值:", df.loc[2, 'close_ffill'])
print("线性插值第3天值:", df.loc[2, 'close_interp'])
预期输出
根据上述代码逻辑,可唯一推出以下结果:
原始数据:
ts_code trade_date close
0 000001.SZ 2024-01-02 10.5
1 000001.SZ 2024-01-03 10.8
2 000001.SZ 2024-01-04 NaN
3 000001.SZ 2024-01-05 11.2
4 000001.SZ 2024-01-06 11.0
5 000001.SZ 2024-01-07 NaN
6 000001.SZ 2024-01-08 11.5
7 000001.SZ 2024-01-09 NaN
8 000001.SZ 2024-01-10 11.8
9 000001.SZ 2024-01-11 12.0
缺失值数量: 3
缺失值所在行索引: [2, 5, 7]
处理后的数据(部分):
trade_date close close_ffill close_interp
0 2024-01-02 10.5 10.5 10.5
1 2024-01-03 10.8 10.8 10.8
2 2024-01-04 NaN 10.8 11.0
3 2024-01-05 11.2 11.2 11.2
4 2024-01-06 11.0 11.0 11.0
5 2024-01-07 NaN 11.0 11.25
6 2024-01-08 11.5 11.5 11.5
7 2024-01-09 NaN 11.5 11.65
8 2024-01-10 11.8 11.8 11.8
9 2024-01-11 12.0 12.0 12.0
落地与运行方式
本案例代码依赖 pandas 和 numpy。将上述代码依次粘贴至Python环境(如Jupyter Notebook或脚本文件)运行即可。若处理真实数据,只需将df替换为从CSV或数据库读取的DataFrame,并确保包含close列即可复用同样的处理逻辑。