在 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]])
我正在尝试创建一组关于财务数据的滚动协方差矩阵(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]])