1. 金融数据获取与清洗

金融数据获取与清洗:股票日线数据 学习卡片

任务说明

本案例从 Yahoo Finance 拉取 3 只股票的日线行情(AAPL、MSFT、SPY),合并为统一时间索引的收盘价面板,并完成缺失值前向填充与异常值(单日涨跌幅超过 20%)的识别与修正。最终输出一个干净的 DataFrame,可直接用于后续特征工程。

环境依赖

pip install yfinance pandas numpy

实现代码

import numpy as np
import pandas as pd
import yfinance as yf

TICKERS = ["AAPL", "MSFT", "SPY"]
START, END = "2022-01-01", "2023-12-31"

# 1. 获取多只股票日线数据
raw = yf.download(TICKERS, start=START, end=END, auto_adjust=True, progress=False)
close = raw["Close"].copy()          # 只保留收盘价,列为 ticker
close.index = pd.to_datetime(close.index)
close = close.sort_index()

# 2. 统一时间索引:以交易日并集为基准,缺失值前向填充
full_idx = pd.date_range(close.index.min(), close.index.max(), freq="B")
close = close.reindex(full_idx).ffill()

# 3. 异常值处理:单日涨跌幅绝对值 > 20% 视为异常,用前一日值替换
returns = close.pct_change()
mask = returns.abs() > 0.20
close_clean = close.mask(mask).ffill()

# 4. 汇总报告
report = pd.DataFrame({
    "缺失值(原始)": raw["Close"].isna().sum(),
    "异常值(修正)": mask.sum(),
    "最终缺失": close_clean.isna().sum(),
})
print(report)
print(close_clean.tail())

# 5. 保存
close_clean.to_csv("clean_close.csv")

关键点说明

  • yf.download 一次请求多只股票,返回 MultiIndex 列,取 "Close" 层得到收盘价面板。
  • 用 reindex 到工作日频率再 ffill,保证三只股票共享同一时间索引,避免后续对齐错位。
  • 异常值判定基于 pct_change,阈值 20% 可按标的波动性调整;mask + ffill 用前值替换异常点。

运行与验证

  1. 执行脚本,观察 report:三只股票原始缺失值应接近 0(Yahoo 日线通常完整),异常值数量为个位数级别。
  2. close_clean.tail() 应显示 2023-12-29 附近三只股票的收盘价,且无 NaN。
  3. 检查 clean_close.csv 已生成,行数等于 2022-01-03 至 2023-12-29 的工作日数量(约 520 行)。
  4. 通过条件:close_clean.isna().sum().sum() == 0 且 close_clean.pct_change().abs().max().max() <= 0.20。

常见问题

  • 若 yf.download 返回空,检查网络或 Yahoo 接口限流,可加 threads=False 重试。
  • 若某只股票停牌导致长段缺失,ffill 会延续旧价,建议对停牌超过 5 日的区间单独标记而非直接填充。