如何在不使用corr()的情况下手动获取Pandas指定列的方差-协方差矩阵
手动计算指定列的方差-协方差矩阵(不用Pandas
.cov()) 嘿,你已经找对路子啦!用np.cov()确实是绕开Pandas内置.cov()方法计算协方差矩阵的好办法,不过可能需要调整几个参数让结果更贴合你的需求,甚至可以彻底手动实现——我来一步步给你讲清楚:
一、用np.cov()正确计算(最简便的手动方式)
你之前的代码得到了一个numpy数组,但可能没注意到np.cov()的默认参数坑:它默认rowvar=True,也就是把每行当作一个变量,但你的DataFrame里显然是每列代表一个变量(比如"AAPL R"是一只股票的收益率列)。所以需要做个小调整:
两种正确调用方式:
import numpy as np import pandas as pd # 1. 直接设置rowvar=False,告诉np每列是变量 cov_array = np.cov(data1.loc[:, 'AAPL R':], rowvar=False) # 2. 转置数据,让原来的列变成行(即每行对应一个变量) cov_array = np.cov(data1.loc[:, 'AAPL R':].T)
转成Pandas DataFrame更直观
numpy数组没有列名和索引,转成DataFrame后就能和原数据的列对应上,方便查看:
# 获取目标列的名称 target_columns = data1.loc[:, 'AAPL R':].columns # 把数组转换成带索引和列名的DataFrame cov_df = pd.DataFrame(cov_array, index=target_columns, columns=target_columns)
这时候得到的cov_df和直接调用data1.loc[:, 'AAPL R':].cov()的结果完全一致!
二、彻底手动实现(从公式出发)
如果想完全从零开始写,那就要用到协方差的样本计算公式:
样本协方差:
Cov(X,Y) = [(X-X̄)(Y-Ȳ)]的和 / (n-1),其中n是样本数量
步骤如下:
- 对目标列做中心化处理(每个值减去该列的均值)
- 用矩阵乘法计算交叉乘积
- 除以(n-1)得到无偏估计的协方差矩阵
代码实现:
# 提取目标列 data_subset = data1.loc[:, 'AAPL R':] # 中心化数据:每个元素减去对应列的均值 centered_data = data_subset - data_subset.mean() # 计算协方差矩阵:转置后做矩阵乘法,再除以样本数-1 manual_cov_df = centered_data.T @ centered_data / (len(centered_data) - 1)
这个结果和前面两种方法得到的完全一样,彻底实现了手动计算!
小验证
你可以用下面的代码确认结果一致性:
# 对比三种方法的结果 print(np.allclose(cov_df, data_subset.cov())) # 应该返回True print(np.allclose(manual_cov_df, data_subset.cov())) # 也应该返回True
内容的提问来源于stack exchange,提问作者Coolio2654
相关产品推荐
相关产品推荐

