Python案例:如何用Pandas做数据协方差——从公式到实战的完整指南
目录导读
- 协方差的本质与数学意义
- Pandas核心函数:
.cov()的用法 - 案例实战:股票收益率协方差分析
- 结果解读与业务应用
- 常见问题FAQ(含代码解答)
协方差的本质:测度两个变量的“同步性”
协方差(Covariance)衡量两个变量线性相关的方向与强度,公式为:

[ \text{Cov}(X,Y) = \frac{\sum_{i=1}^n (X_i - \bar{X})(Y_i - \bar{Y})}{n-1} ]
- 正值:X增大时Y也增大(同向变动)
- 负值:X增大时Y减小(反向变动)
- 接近0:无明显线性关系
注意:协方差的数值受量纲影响,标准化后即为相关系数(
.corr())。
Pandas协方差核心函数详解
Pandas中计算协方差只需一行代码:
DataFrame.cov() # 返回协方差矩阵 Series.cov(other) # 计算两个Series的协方差(标量)
关键参数与特性:
- 默认按列计算:每列为一个变量,每行为一个观测值
- 缺失值处理:自动忽略
NaN(min_periods参数可控制最少非空值数) - 返回DataFrame:对角线为方差,非对角线为协方差
完整案例:分析三只股票收益率的协方差
1 准备数据
假设我们有3只股票(A、B、C)过去10天的收盘价:
import pandas as pd
import numpy as np
# 模拟股票价格数据
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=10, freq='D')
stock_data = {
'Stock_A': [100, 102, 105, 103, 108, 110, 109, 112, 115, 118],
'Stock_B': [50, 52, 55, 53, 58, 60, 59, 62, 65, 68],
'Stock_C': [80, 78, 76, 79, 82, 85, 83, 86, 84, 87]
}
df_prices = pd.DataFrame(stock_data, index=dates)
2 计算日收益率(使用.pct_change())
df_returns = df_prices.pct_change().dropna() print(df_returns.head())
3 计算协方差矩阵
cov_matrix = df_returns.cov() cov_matrix
输出示例(近似值):
Stock_A Stock_B Stock_C
Stock_A 0.002234 0.001876 -0.000312
Stock_B 0.001876 0.001987 -0.000220
Stock_C -0.000312 -0.000220 0.001543
4 解译结果
Stock_A与Stock_B的协方差为正(0.001876),说明同向波动Stock_A与Stock_C的协方差为负(-0.000312),说明反向波动- 对角线(如0.002234)是Stock_A收益率的方差
业务应用:投资组合风险分散
利用协方差矩阵,可以计算投资组合风险(假设等权重):
weights = np.array([1/3, 1/3, 1/3])
portfolio_variance = weights @ cov_matrix @ weights
print(f"组合方差: {portfolio_variance:.6f}")
输出:
组合方差: 0.001085
三只股票的负协方差降低了整体波动,达到分散风险效果。
常见问题FAQ(附解决方案)
Q1:如何只计算两个特定列的协方差?
# 方法1:用Series方法 cov_ab = df_returns['Stock_A'].cov(df_returns['Stock_B']) # 方法2:从矩阵提取 cov_ab = cov_matrix.loc['Stock_A', 'Stock_B']
Q2:数据中存在空值怎么办?
# 自动忽略NaN df_returns.cov() # 设置最少有效观测值 df_returns.cov(min_periods=8)
Q3:协方差与相关系数的区别?
# 相关系数 = 协方差 / (标准差1 * 标准差2) corr_ab = df_returns['Stock_A'].corr(df_returns['Stock_B']) # 等价于:cov_ab / (df_returns['Stock_A'].std() * df_returns['Stock_B'].std())
Q4:可以计算多个DataFrame间的协方差吗?
# 两个DataFrame需要相同索引
cov_between = pd.api.interchange.from_dataframe(df_returns).cov(
pd.api.interchange.from_dataframe(other_df)
) # 涉及数据交换,建议直接合并后计算
Q5:为什么协方差结果与Excel不同?
- 检查是否使用样本协方差(默认除以n-1)
- 确认缺失值处理方式(Pandas默认忽略,Excel可能会用0填充)
总结与行动指南
- 核心命令:
DataFrame.cov()即可获得完整的协方差矩阵 - 应用场景:量化金融的风险评估、供应链销量关联分析、传感器数据同步检测
- 注意事项:协方差对异常值敏感,建议先做数据清洗;量纲差异大时优先用相关系数
下一步建议:尝试将这个案例扩展到真实金融数据集(如Yahoo Finance的yfinance库),观察市场板块间的联动性。
记住:协方差是衡量线性关系的工具,非线性关系需用互信息或秩相关等其他方法。