第一章:Python金融分析基础
各位同学好,我是老张。在量化投资这个行当摸爬滚打了十几年,我越来越觉得——Python就是咱们量化人的瑞士军刀。今天咱们就从最基础的两个库开始:NumPy和Pandas。
说实话,我刚入行那会儿,还在用Excel处理数据。每天对着几万行数据,手动拉公式,眼睛都快瞎了。后来接触了Python,才发现原来数据处理可以这么优雅。嗯,咱们直接进入正题。
1.1 NumPy:高性能数值计算的基石
NumPy,全称是Numerical Python。说白了,它就是Python世界里做数学运算的"发动机"。为什么这么说?因为Python原生的列表做运算实在太慢了。
核心概念:NumPy的核心是ndarray(N维数组)对象。它比Python列表快10-100倍,原因在于底层用C语言实现,而且支持向量化操作。
我个人习惯,拿到金融数据第一件事就是转成NumPy数组。来看个例子:
import numpy as np
# 创建股票收益率数组
returns = np.array([0.02, -0.01, 0.03, -0.005, 0.015])
print(f"平均收益率: {returns.mean():.4f}")
print(f"收益率标准差: {returns.std():.4f}")
print(f"累计收益率: {(1 + returns).prod() - 1:.4f}")
# 向量化运算——这才是精髓
prices = np.array([100, 102, 101, 104, 103.5])
daily_returns = np.diff(prices) / prices[:-1]
print(f"日收益率: {daily_returns}")
我在项目中遇到过一个问题:用Python列表计算500万行数据的移动平均,跑了整整3分钟。换成NumPy后,0.3秒就出结果了。你想想看,这差距有多大?
1.2 Pandas:金融数据的"瑞士军刀"
NumPy解决了计算速度问题,但金融数据还有两个特点:带标签、有时间序列。这就是Pandas登场的时候了。
Pandas有两个核心数据结构:
- Series:一维带标签数组,相当于带索引的列表
- DataFrame:二维表格数据,相当于带行列标签的Excel表格
我建议你记住这个比喻:DataFrame就是Excel表格的Python版本,但功能强大100倍。
import pandas as pd
import numpy as np
# 创建股票数据DataFrame
dates = pd.date_range('2024-01-01', periods=5, freq='D')
stock_data = pd.DataFrame({
'开盘价': [100, 102, 101, 104, 103],
'收盘价': [102, 101, 104, 103, 105],
'成交量': [10000, 12000, 9000, 15000, 11000]
}, index=dates)
print(stock_data)
print(f"\n收盘价均值: {stock_data['收盘价'].mean():.2f}")
# 计算收益率——Pandas一行搞定
stock_data['收益率'] = stock_data['收盘价'].pct_change()
print(f"\n收益率数据:\n{stock_data['收益率']}")
避坑指南:我曾经在回测时发现收益率计算总差一点点,排查了半天才发现是pct_change()默认用前值做分母,而我想用开盘价。记住:Pandas的pct_change()默认是shift(1),不是shift(0)。
1.3 数据清洗:金融数据的"必修课"
真实世界的金融数据,从来都不是干干净净的。缺失值、异常值、重复值,你总会遇到。我处理过的数据里,大概有5%-10%需要清洗。
# 模拟脏数据
dirty_data = pd.DataFrame({
'price': [100, np.nan, 102, 101, np.nan, 104],
'volume': [10000, 12000, None, 9000, 15000, 11000]
})
# 检查缺失值
print("缺失值统计:")
print(dirty_data.isnull().sum())
# 填充缺失值——我常用的方法
dirty_data['price'].fillna(method='ffill', inplace=True) # 前向填充
dirty_data['volume'].fillna(dirty_data['volume'].median(), inplace=True) # 中位数填充
print(f"\n清洗后数据:\n{dirty_data}")
注意:千万别用均值填充金融时间序列!股票价格有趋势性,用均值填充会引入未来信息。我见过有人因此回测曲线漂亮得不行,实盘却亏得底掉。前向填充(ffill)或插值法才是正道。
1.4 Matplotlib与Seaborn:让数据"说话"
数据算完了,不可视化等于白干。我个人习惯用Matplotlib做基础图表,Seaborn做统计图表。为什么?因为Matplotlib灵活但代码啰嗦,Seaborn简洁但定制性差。两者搭配,天下无敌。
import matplotlib.pyplot as plt
import seaborn as sns
# 生成模拟数据
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=100, freq='D')
prices = 100 + np.cumsum(np.random.randn(100) * 0.5)
# Matplotlib画折线图
plt.figure(figsize=(12, 5))
plt.plot(dates, prices, label='股价走势', color='#2196F3', linewidth=2)
plt.title('股票价格走势图', fontsize=14)
plt.xlabel('日期')
plt.ylabel('价格')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
# Seaborn画收益率分布
returns = pd.Series(np.diff(prices) / prices[:-1], index=dates[1:])
plt.figure(figsize=(10, 5))
sns.histplot(returns, bins=30, kde=True, color='#FF5722')
plt.title('收益率分布直方图', fontsize=14)
plt.xlabel('日收益率')
plt.ylabel('频次')
plt.show()
为什么会这样?因为金融数据往往呈现尖峰厚尾分布,用直方图加核密度估计(KDE)能直观看出极端值情况。我在做风险分析时,这个图是必看的。
1.5 知识体系总览
说了这么多,咱们用一张图把本章的知识结构串起来:
这张图就是咱们本章的"作战地图"。从左到右,从原始数据到最终的可视化结果,每一步都有对应的工具。你想想看,有了这套体系,处理金融数据是不是清晰多了?
1.6 实战小贴士
最后,分享几个我这些年总结的经验:
| 场景 | 推荐工具 | 我的经验 |
|---|---|---|
| 大规模矩阵运算 | NumPy | 比Python列表快50倍以上 |
| 表格数据清洗 | Pandas | fillna()配合ffill最常用 |
| 时间序列分析 | Pandas + Matplotlib | rolling()做移动平均很顺手 |
| 收益率分布分析 | Seaborn | histplot + kde 是标配 |
我的建议:刚开始学的时候,别贪多。先把NumPy的数组操作和Pandas的DataFrame基础操作练熟。我当年就是靠这两个工具,把一个需要3天的手工报表,压缩到了10分钟自动生成。嗯,那种成就感,你试过就知道。
好了,第一章的内容就到这里。记住:工具是死的,思路是活的。多动手,多思考,你也能成为量化高手。