跳到主内容
研究工具量化研究工具与数据基础 · 第1–5讲4/5模块导览 →
讲义

第4讲:Pandas入门 (Introduction to pandas)

围绕金融时间序列介绍 Series、DataFrame、索引、缺失值、重采样和滚动统计,并展示数据对齐流程。

完成状态保存在当前浏览器,可随时取消。

1. Pandas简介与安装#

Pandas是Python的数据分析核心库,提供高效的SeriesDataFrame数据结构,专为处理结构化数据设计。

安装

code
pip install pandas numpy matplotlib

基础导入

code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

2. Series:一维数据处理#

2.1 创建与属性#

code
# 从列表创建Series
s = pd.Series([1, 2, np.nan, 4, 5], name="Toy Series")
print(s)

输出:

code
0    1.0
1    2.0
2    NaN
3    4.0
4    5.0
Name: Toy Series, dtype: float64

设置索引

code
s.index = pd.date_range("2023-01-01", periods=5, freq="D")
print(s.index)

输出:

code
DatetimeIndex(['2023-01-01', '2023-01-02', ..., '2023-01-05'], dtype='datetime64[ns]', freq='D')

2.2 索引操作#

按位置访问

code
print(s.iloc[0])  # 第一个元素 → 1.0
print(s.iloc[1:4])  # 切片

按日期访问

code
print(s.loc['2023-01-02'])  # 2.0
print(s.loc['2023-01-02':'2023-01-04'])

2.3 缺失数据处理#

code
# 填充缺失值
s_filled = s.fillna(s.mean())
print(s_filled)

# 删除缺失值
s_dropped = s.dropna()

2.4 时间序列处理#

重采样(日数据→月数据):

code
monthly_data = s.resample('M').mean()
print(monthly_data)

时区转换

code
s_utc = s.tz_localize('UTC')
s_eastern = s_utc.tz_convert('US/Eastern')

3. DataFrame:二维数据处理#

3.1 创建与结构#

code
data = {
    'A': np.random.randn(5),
    'B': ['X', 'Y', 'Z', 'W', 'V'],
    'C': pd.date_range('2023-01-01', periods=5)
}
df = pd.DataFrame(data)
print(df.head())

3.2 列操作与布尔索引#

添加/删除列

code
df['D'] = df['A'] * 2
df = df.drop('B', axis=1)

布尔筛选

code
filtered = df[df['A'] > 0]  # 筛选A列正值的行

3.3 合并数据#

code
df1 = pd.DataFrame({'X': [1,2], 'Y': [3,4]})
df2 = pd.DataFrame({'X': [5,6], 'Y': [7,8]})
combined = pd.concat([df1, df2])

3.4 时间序列分析#

滚动均值与波动率

code
df['Rolling_Mean'] = df['A'].rolling(30).mean()
df['Rolling_Std'] = df['A'].rolling(30).std()

收益率计算

code
returns = df.pct_change()

4. 核心函数深度解析#

4.1 pct_change:收益率计算技巧#

功能:计算当前元素与前一个元素的百分比变化,常用于金融收益率计算。

基础用法

code
# 生成示例数据
prices = pd.Series([100, 105, 110, 108, 115])
returns = prices.pct_change()  # 默认计算单日收益率
print(returns)
code
0         NaN
1    0.050000
2    0.047619
3   -0.018182
4    0.064815
dtype: float64

高级技巧

  • 多期收益率:通过periods参数调整计算间隔
code
# 计算3日收益率(当前vs前第3日)
long_returns = prices.pct_change(periods=3)
print(long_returns)
code
0         NaN
1         NaN
2         NaN
3    0.080000  # (108-100)/100
4    0.095238  # (115-105)/105
dtype: float64
  • 处理初始NaN:配合dropna清理数据
code
clean_returns = returns.dropna()
print(clean_returns)

注意事项

  • 第一个元素总是NaN(没有前值可比较)

  • 收益率计算方式:(当前值 - 前值) / 前值

  • 对DataFrame使用时,每列独立计算


4.2 rolling:滚动计算全攻略#

功能:创建滑动窗口对象,用于计算滚动统计量。

基础架构

code
# 创建20日滚动窗口
rolling_window = prices.rolling(window=20)

常用统计量

code
# 滚动均值与标准差
ma_20 = rolling_window.mean()
std_20 = rolling_window.std()

# 直接链式写法
ma_20 = prices.rolling(20).mean()

完整示例

code
# 生成100日随机数据
np.random.seed(42)
data = pd.Series(np.random.normal(0, 1, 100))

# 计算不同窗口的滚动均值
windows = [5, 20, 50]
for w in windows:
    data.rolling(w).mean().plot(label=f'{w}日均线')

plt.legend()
plt.title("不同窗口的移动平均线对比")
plt.show()

关键参数详解

参数说明示例
window窗口大小window=30(30日窗口)
min_periods最小计算数据量min_periods=5(至少5个数据点)
center窗口居中center=True(当前点位于窗口中间)

实战技巧

  1. 处理初期波动:设置min_periods=1允许初始阶段计算
code
smooth_data = prices.rolling(30, min_periods=1).mean()
  1. 滚动相关性计算
code
# 假设df包含两列价格数据
rolling_corr = df['A'].rolling(60).corr(df['B'])
  1. 自定义滚动函数
code
def my_roll_func(x):
    return (x.max() - x.min())/2

custom_roll = prices.rolling(10).apply(my_roll_func)

常见误区警示

  • 窗口选择过大:导致信号严重滞后(建议结合数据频率选择)

  • 忽视NaN处理:滚动计算初期会产生NaN,使用fillnadropna处理

  • 误解窗口位置:默认窗口包含当前点之前的window-1个历史点


5. 实战演练:金融数据处理#

演练一:完整分析流程

code
# 获取数据(示例使用随机数据)
dates = pd.date_range('2023-01-01', periods=100, freq='D')
prices = pd.DataFrame({
    'AAPL': np.cumprod(1 + np.random.normal(0.001, 0.02, 100)),
    'GOOG': np.cumprod(1 + np.random.normal(0.0008, 0.015, 100))
}, index=dates)

# 计算5日收益率
returns = prices.pct_change(5).dropna()

# 计算双均线系统
prices['AAPL_MA20'] = prices['AAPL'].rolling(20).mean()
prices['AAPL_MA60'] = prices['AAPL'].rolling(60).mean()

# 可视化
plt.figure(figsize=(12,6))
prices[['AAPL', 'AAPL_MA20', 'AAPL_MA60']].plot()
plt.title('苹果股价双均线系统')
plt.ylabel('价格')
plt.show()

输出分析

  • 金叉(短均线上穿长均线)提示买入信号

  • 死叉(短均线下穿长均线)提示卖出信号

  • 20日均线比60日均线更敏感

演练二:生成随机收益并绘制价格曲线

code
returns = pd.DataFrame(np.random.normal(0.01, 0.03, (100, 5)),
                       columns=['Stock1', 'Stock2', 'Stock3', 'Stock4', 'Stock5'])
prices = (1 + returns).cumprod()
prices.plot(figsize=(10,6))
plt.title('模拟股票价格走势')
plt.xlabel('日期')
plt.ylabel('价格')
plt.legend(loc='upper left')
plt.show()

6. 总结与资源#

核心要点回顾

  • Series是带索引的一维数据容器

  • DataFrame是二维表格,支持列式操作

  • pct_change是收益率计算的核心工具

  • rolling实现移动窗口分析

  • 始终优先使用.loc/.iloc进行索引

进阶学习路径

  1. 官方文档:pandas.pydata.org

  2. 实践项目:分析股票RSI指标(使用rolling计算)

  3. 扩展库学习:pandas_datareader获取真实金融数据

避坑指南

  • 避免df[column]直接赋值,使用df.assign()[]操作

  • 时间序列操作前务必sort_index()

  • 滚动计算后立即处理NaN值


本节介绍了 pandas 的主要操作及其在金融数据分析中的用法。可使用下方 yfinance 示例获取真实股票数据,复现清洗、计算与可视化流程。

code
import yfinance as yf

# 获取苹果公司历史数据
aapl = yf.download('AAPL', start='2020-01-01', end='2023-01-01')
aapl['MA50'] = aapl['Close'].rolling(50).mean()
aapl[['Close', 'MA50']].plot(figsize=(10,6))