我想拍摄一个有两列的pandas DataFrame,并计算两列之间的滚动协方差。问题在于,有时我想假设平均值为零,有时我会想要正确的样本协方差。
要做到这一点,我有以下函数,我想使用滚动应用 - 所有这一切都是计算协方差,假设零均值,如果没有居中,并计算它居中时的通常协方差。
def real_cov(x,y, centered=True):
return (((x-(x.mean() if centered else 0))*(y-(y.mean() if centered else 0))).sum()/(len(x)-1))
# Make this a binary function
real_cov_uncentered = lambda x,y: real_cov(x,y,False)
现在假设df是一个包含2列和100行数字的DataFrame。
我想使用pandas rolling_apply函数使用我的自定义函数real_cov_uncentered计算未中心的滚动协方差。
即。我希望这段代码能够运作:
rolling_cov=pd.rolling_apply(df, window=20, func=real_cov_uncentered)
这不起作用,因为我显然无法说服pandas将df中的两列视为real_cov_uncentered的两个参数。
有什么建议吗?如果我不清楚我会编辑,请告诉我。
在编辑1上: 我应该补充一点,我对一些hackish聪明的尝试(即使有效也会令人不满意)也失败了:
def zipped_cov(two_tuple, centered=True):
x=np.array([two_tuple[i][0] for i in np.arange(len(two_tuple))])
y=np.array([two_tuple[i][1] for i in np.arange(len(two_tuple))])
return real_cov(x,y,centered)
zipped_df=pd.Series(data=zip(df['col1'], df['col2']), index=df.index)
rolling_cov=pd.rolling_apply(zipped_df, window=20, func=lambda x: zipped_cov(x, False))
在这里,我正在做的是通过将我的两列压缩成一列,然后调用zipped_cov函数强制我的协方差调用成为一元函数,该函数将解压缩并调用原始协方差函数。似乎在引擎盖下,熊猫宁愿呕吐,也不愿为我做这件事:
错误消息:
C:\AppData\Local\Enthought\Canopy32\User\lib\site-packages\pandas\stats\moments.pyc in _process_data_structure(arg, kill_inf)
330
331 if not issubclass(values.dtype.type, float):
--> 332 values = values.astype(float)
333
334 if kill_inf:
ValueError: setting an array element with a sequence.