3. Python金融数据处理基础:Pandas库入门
做量化投资,说白了就是跟数据打交道。我见过太多人策略写得漂亮,结果卡在数据预处理上。今天咱们聊聊Pandas——这个Python里最核心的金融数据处理工具。
我个人习惯,拿到任何金融数据,第一件事就是把它塞进Pandas的DataFrame里。为什么?因为后面所有的清洗、分析、回测,都离不开它。
3.1 DataFrame与Series:金融数据的“容器”
先搞清楚两个基本概念:Series是一列数据,DataFrame是多列组成的表格。你可以把DataFrame想象成Excel表格,Series就是其中一列。
我在项目中遇到过,很多新手上来就用Python原生的list和dict处理行情数据,结果代码越写越乱。其实用Pandas,几行就搞定。
import pandas as pd
import numpy as np
# 创建一个简单的DataFrame,模拟股票数据
data = {
'股票代码': ['000001', '000002', '600519'],
'收盘价': [12.5, 18.3, 1680.0],
'成交量': [1000000, 800000, 50000],
'日期': ['2024-01-05', '2024-01-05', '2024-01-05']
}
df = pd.DataFrame(data)
print(df)
输出结果:
| 股票代码 | 收盘价 | 成交量 | 日期 |
|---|---|---|---|
| 000001 | 12.5 | 1000000 | 2024-01-05 |
| 000002 | 18.3 | 800000 | 2024-01-05 |
| 600519 | 1680.0 | 50000 | 2024-01-05 |
你看,结构清晰,一目了然。Series操作也很简单:
# 提取收盘价这一列(返回Series)
close_prices = df['收盘价']
print(close_prices.mean()) # 计算平均收盘价
df.columns 先看一眼列名,避免后面写错。尤其是从数据库或CSV导入时,列名可能带空格或特殊字符。
3.2 数据清洗与缺失值处理
金融数据从来不会干干净净。停牌、节假日、数据源故障……都会产生缺失值。你想想看,如果回测时因为一个NaN值导致整个策略报错,那多冤。
常见的缺失值处理方式有三种:
- 删除:直接丢掉有缺失的行或列。适合缺失比例很小的情况。
- 填充:用均值、中位数、前值或后值填充。我常用前值填充(ffill),因为金融数据有连续性。
- 插值:用线性或多项式插值。适合时间序列数据。
# 模拟有缺失的数据
df_with_na = pd.DataFrame({
'收盘价': [12.5, np.nan, 18.3, np.nan, 1680.0],
'成交量': [1000000, 800000, np.nan, 50000, 60000]
})
# 检查缺失值
print(df_with_na.isnull().sum())
# 前值填充(金融数据常用)
df_filled = df_with_na.fillna(method='ffill')
print(df_filled)
dropna() 删除了所有缺失行,结果发现连续几天的数据被删掉,导致策略信号错位。后来我改用前值填充,效果好了很多。千万别盲目删除!
3.3 时间序列数据处理
量化投资的核心就是时间序列。股票价格、期货合约、宏观经济指标……全是按时间排列的。Pandas对时间序列的支持非常强大。
首先,要把日期列转成时间类型:
# 将日期列转为datetime类型
df['日期'] = pd.to_datetime(df['日期'])
# 设置为索引
df.set_index('日期', inplace=True)
print(df.index)
设置好时间索引后,很多操作就方便了。比如按时间切片:
# 选取2024年1月的数据
df_jan = df['2024-01']
print(df_jan)
再比如重采样——把日线数据聚合成周线或月线:
# 模拟日线数据
dates = pd.date_range('2024-01-01', periods=10, freq='D')
prices = np.random.randn(10).cumsum() + 100
df_daily = pd.DataFrame({'收盘价': prices}, index=dates)
# 重采样为周线,取每周最后一个交易日
df_weekly = df_daily.resample('W').last()
print(df_weekly)
resample() 和 shift() 是我最常用的两个函数。前者用于改变数据频率,后者用于计算收益率(比如 df['收益率'] = df['收盘价'].pct_change())。
嗯,这里要注意一点:金融数据的时间索引最好统一成UTC或北京时间,避免时区问题。我吃过这个亏——从不同数据源拿到的数据,时区不一致,合并时对不上。
3.4 知识体系总览
下面这张图,是我梳理的Pandas金融数据处理核心流程。你照着这个思路走,基本不会乱。
说白了,Pandas就是量化投资的“地基”。地基打不牢,上面盖多高的楼都危险。我建议你拿到任何金融数据,都先用Pandas走一遍这个流程,养成习惯。
最后分享一个经验:永远先做数据探索。用 df.info() 看数据类型,用 df.describe() 看统计分布,用 df.head() 看前几行。花5分钟了解数据全貌,能省下后面2小时的debug时间。