2、Python金融数据处理基础:Pandas库核心操作、NumPy数组运算、金融数据获取与清洗

说实话,做量化回测这么多年,我最大的体会就是——数据才是真正的老大。策略再牛,模型再花哨,数据一塌糊涂,结果就是垃圾进垃圾出。这一章,咱们就把金融数据处理的基础打扎实。

2.1 NumPy数组运算:量化计算的基石

NumPy这东西,说白了就是Python里的数学引擎。我刚开始做量化时,用纯Python列表算收益率,一个回测跑下来要半小时。后来换成NumPy,十几秒搞定。差距就这么大。

核心操作速览

操作 代码示例 说明
创建数组 np.array([1,2,3]) 从列表创建
向量化运算 prices * 1.1 每个元素都乘1.1
统计函数 np.mean(returns) 计算均值
矩阵运算 np.dot(A, B) 矩阵乘法

重点记住:NumPy的向量化操作比Python循环快几十倍。能用数组运算就别写for循环。

import numpy as np

# 模拟股票价格序列
prices = np.array([100, 102, 101, 105, 108])

# 计算日收益率(向量化,一行搞定)
returns = np.diff(prices) / prices[:-1]
print("日收益率:", returns)

# 计算年化波动率
volatility = np.std(returns) * np.sqrt(252)
print("年化波动率:", round(volatility, 4))

我在项目中遇到过一个问题:用纯Python算5000只股票的协方差矩阵,跑了整整一个晚上。换成NumPy的np.cov(),3分钟出结果。嗯,这就是差距。

2.2 Pandas核心操作:时间序列的瑞士军刀

Pandas就是为金融数据而生的。它最牛的地方在于——天然支持时间序列索引。你想想看,股票数据、期货数据、宏观经济数据,哪个不是按时间排列的?

DataFrame基础操作

import pandas as pd

# 创建时间序列数据
dates = pd.date_range('2024-01-01', periods=5, freq='D')
data = {
    'close': [100, 102, 101, 105, 108],
    'volume': [10000, 12000, 9000, 15000, 11000]
}
df = pd.DataFrame(data, index=dates)

print(df.head())

常用操作一览

  • 数据选取:df['close'] 选列,df.loc['2024-01-03'] 选行
  • 条件筛选:df[df['volume'] > 10000]
  • 缺失值处理:df.dropna()df.fillna(method='ffill')
  • 滚动计算:df['close'].rolling(window=5).mean()

我的习惯:拿到数据第一件事,先看df.info()df.describe()。花30秒了解数据全貌,能避免后面踩很多坑。

2.3 金融数据获取:Tushare与Yahoo Finance

数据从哪来?国内用Tushare,国外用Yahoo Finance。这两个我都在用,各有千秋。

Tushare获取A股数据

import tushare as ts

# 设置token(需要去tushare官网注册)
ts.set_token('your_token_here')
pro = ts.pro_api()

# 获取贵州茅台日线数据
df = pro.daily(ts_code='600519.SH', 
               start_date='20240101', 
               end_date='20240131')
print(df.head())

注意:Tushare的免费版有调用频率限制,每分钟最多200次。我建议把数据存到本地,别每次都去拉。

Yahoo Finance获取美股数据

import yfinance as yf

# 获取苹果公司数据
aapl = yf.download('AAPL', start='2024-01-01', end='2024-01-31')
print(aapl.head())

我曾经犯过一个错:直接用Yahoo Finance拉A股数据,结果发现数据对不上。后来才明白,Yahoo Finance的A股数据延迟严重,而且复权处理有问题。所以我现在坚持:A股用Tushare,美股用Yahoo Finance

2.4 数据清洗与预处理:80%的时间花在这

说实话,量化交易里最枯燥的就是数据清洗。但这一步做不好,后面全是白费。我见过太多人,策略写得很漂亮,结果因为数据里有几个空值,回测结果完全失真。

常见问题与处理

问题 处理方法 代码示例
缺失值 前向填充或插值 df.fillna(method='ffill')
异常值 3倍标准差剔除 df[np.abs(df - df.mean()) <= 3*df.std()]
重复数据 去重 df.drop_duplicates()
日期对齐 重采样 df.resample('D').last()

实战:完整的数据清洗流程

def clean_stock_data(df):
    """
    我的标准清洗流程
    """
    # 1. 去除全空的行
    df = df.dropna(how='all')
    
    # 2. 前向填充缺失值(用前一天的数据)
    df = df.fillna(method='ffill')
    
    # 3. 如果还有缺失,用后向填充
    df = df.fillna(method='bfill')
    
    # 4. 去除重复索引
    df = df[~df.index.duplicated(keep='first')]
    
    # 5. 排序索引(确保时间顺序)
    df = df.sort_index()
    
    return df

# 使用示例
clean_df = clean_stock_data(raw_df)

核心原则:数据清洗没有银弹。每只股票、每个市场都有自己的脾气。我的建议是——先可视化看看数据长什么样,再决定怎么清洗。

2.5 本章知识体系总览

下面这张图,是我自己总结的数据处理流程。每次做新项目,我都会先过一遍这个流程。

金融数据处理流程 数据获取 NumPy数组运算 Pandas核心操作 数据清洗预处理 干净可用的数据 量化回测 数据获取 → 数组/DataFrame处理 → 清洗 → 回测

你看这个流程,其实就三步:拿数据 → 处理数据 → 用数据。但每一步都有坑。我刚开始做量化时,在数据清洗上栽过跟头——用错了填充方法,导致回测结果虚高。后来学乖了,每次清洗完都做一遍可视化检查。

避坑指南:我曾经因为没处理停牌数据,导致回测收益率虚高20%。记住:停牌日的价格是无效的,必须用前一天的收盘价填充,或者直接剔除。

好了,这一章的内容就这些。记住我说的:数据质量决定回测质量。把Pandas和NumPy练熟了,后面的路就好走了。

专注资料整理