2. 金融时序缺失值处理与对齐

任务说明

本案例对多只股票的收盘价按交易日对齐,先做前向填充(ffill),再用线性插值补齐仍缺失的值,最后计算日收益率矩阵。输入为三只股票在若干交易日上的收盘价,其中包含缺失值。

依赖

pip install pandas numpy

完整实现

import numpy as np
import pandas as pd

# 构造原始数据:索引为交易日,列为股票代码,含缺失值
raw = pd.DataFrame(
    {
        "AAPL": [150.0, np.nan, 153.0, np.nan, np.nan, 158.0],
        "MSFT": [280.0, 282.0, np.nan, np.nan, 288.0, 290.0],
        "GOOG": [np.nan, 101.0, 102.5, np.nan, 104.0, np.nan],
    },
    index=pd.to_datetime(
        ["2024-01-02", "2024-01-03", "2024-01-04",
         "2024-01-05", "2024-01-08", "2024-01-09"]
    ),
)

# 1) 日期对齐:以所有出现过的交易日为并集索引
aligned = raw.reindex(raw.index.union(raw.index)).sort_index()

# 2) 前向填充
ffilled = aligned.ffill()

# 3) 线性插值(按时间轴),补齐仍缺失的值
filled = ffilled.interpolate(method="linear", limit_direction="both")

# 4) 计算日收益率矩阵
returns = filled.pct_change().dropna()

print("对齐并填充后的收盘价:")
print(filled.round(4))
print("\n收益率矩阵:")
print(returns.round(6))

运行方式

python align_returns.py

验证方法与通过条件

  • 填充后 filled 中不应存在 NaN,且索引为 6 个交易日、列为 3 只股票。
  • 前向填充效果:AAPL 在 2024-01-03 的值应等于 2024-01-02 的 150.0。
  • 插值效果:AAPL 在 2024-01-05 与 2024-01-08 之间由 153.0 与 158.0 线性插值得到。
  • 收益率矩阵 returns 形状为 (5, 3),无 NaN,首行对应 2024-01-03。
  • 满足以上条件即判定通过。

关键点

前向填充适合处理停牌等“价格延续”场景;插值用于填补序列首尾或长段缺失。两者顺序不能颠倒,否则插值会掩盖前向填充应保留的延续性。收益率用 pct_change() 计算,需在填充完成后进行,避免缺失值污染收益率。