这个问题与我在这里的另一个问题有关。
我想计算pandas数据框架中两列之间的滚动指数加权相关性。
import pandas as pd
import numpy as np
n_obs = 10000
window = 260
min_obs = 130
halflife = 130
# create a dummy dataframe
df = pd.DataFrame(np.random.rand(n_obs, 2), columns=['A', 'B'])
# initialize weights
w = 0.5**((window-np.arange(window)-1)/(halflife-1))
# correlation for a single sliding window.
# note because of `min_obs`, df_win might be of various lengths
def _corr_single_window_(df_win):
return df_win.mul(w[-df_win.shape[0]:], axis=0).corr().iloc[0, 1]
# test on the dummy dataframe
df.rolling(window=window, min_periods=min_obs).apply(_corr_single_window_)
字符串
我得到了这个错误:
DataError:没有要聚合的数值类型
1条答案
按热度按时间im9ewurl1#
您收到此错误的原因是因为
df_win
实际上是pd.Series
。.rolling.apply
不通过pd.DataFrame
,因此相关性计算是不可能的-因为只有一个数据系列。在this answer中有更多的解释。以下是计算问题中相关性的几个选项:
选项1 -滚动申请
使用与您几乎相同的代码,我将其改为在返回代码的开头使用全局变量
df
,以便使用两列,而不是df_win
中的单个列(因为这是一个pd.Series
。此外,我还将调用函数的行更改为仅对单个列运行,否则输出将返回两次。字符串
选项2 -列表解析
这个列表解析计算
min_obs
有一个if else语句,并使用max(0, i-window)
作为.iloc
的下限,因此它从min_obs
的开始增加到完整的window
长度。如果您使用的是Python>=3.8
,则可以在中使用"walrus operator"来避免重复此计算。型
选项3 -带卷管
主要改编自this answer,它使用
.pipe
将函数链接在一起。型
从上面的时序可以看出,第三个选项是最有效的。然而,鉴于大量的观察结果,仅进行了7次运行,并且多次测试给出了相当不同的时间。