在 pandas 中创建滚动协方差矩阵

Create rolling covariance matrix in pandas

我正在尝试创建一组关于财务数据的滚动协方差矩阵(window 大小 = 60)。 Returns 是 125x3 df.

import pandas as pd

roll_rets = returns.rolling(window=60)
Omega = roll_rets.cov()

Omega 是一个 375x3 的数据框,看起来像一个多索引——即每个时间戳有 3 个值。

我真正想要的 return 是一组 66 个 3x3 协方差矩阵(即每个周期一个),但我不知道如何正确迭代 returns去做这个。我想我错过了一些明显的东西。谢谢

首先:MultiIndex DataFrame 是一个可迭代对象。 (尝试 bool(pd.DataFrame.__iter__)。如果您有兴趣,有几个关于遍历 MultiIndex DataFrame 的子帧的 Whosebug 问题。

但对于你的直接问题,这里有一个字典:键是(结束)日期,每个值是一个 3x3 NumPy 数组。

import pandas as pd
import numpy as np

Omega = (pd.DataFrame(np.random.randn(125,3), 
                      index=pd.date_range('1/1/2010', periods=125),
                      columns=list('abc'))
         .rolling(60)
         .cov()
         .dropna()) # this will get you to 66 windows instead of 125 with NaNs

dates = Omega.index.get_level_values(0) # or just the index of your base returns
d = dict(zip(dates, [Omega.loc[date].values for date in dates]))

这样有效率吗?不,不是很。您正在为字典的每个值创建一个单独的 NumPy 数组。每个 NumPy 数组都有自己的 dtype 等。现在的 DataFrame 可以说非常适合您的目的。但另一种解决方案是通过扩展 Omega.values:

ndim 来创建单个 NumPy 数组
Omega.values.reshape(66, 3, 3)

这里每个元素都是一个矩阵(同样,很容易迭代,但会丢失您在 DataFrame 中的日期索引)。

Omega.values.reshape(66, 3, 3)[-1] # last matrix/final date
Out[29]: 
array([[ 0.80865977, -0.06134767,  0.04522074],
       [-0.06134767,  0.67492558, -0.12337773],
       [ 0.04522074, -0.12337773,  0.72340524]])