计算Pandas列上的滚动窗口加权平均值

时间:2017-12-09 19:56:12

标签: python pandas

我是python的新手,并且一直试图在pandas数据框中计算一些简单的滚动加权平均值。我有一个观察数据框df和一个权重w的数据框。我创建了一个新的数据框,用于保存这两组值dot

之间的内积

由于w的维度较小,我使用for循环计算行的加权平均值,前导行的行数等于w的长度。

更清楚的是,我的设置如下:

import pandas as pd

df = pd.DataFrame([0,1,2,3,4,5,6,7,8], index = range(0,9))

w = pd.DataFrame([0.1,0.25,0.5], index = range(0,3))

dot = pd.DataFrame(0, columns = ['dot'], index = df.index)

for i in range(0,len(df)):
    df.loc[i] = sum(df.iloc[max(1,(i-3)):i].values * w.iloc[-min(3,(i-1)):4].values) 

我希望结果如下(即当i = 4

dot.loc[4] = sum(df.iloc[max(1,(4-3)):4].values * w.iloc[-min(3,(4-1)):4].values)
print dot.loc[4]  #2.1

但是,当运行上面的for循环时,我收到错误:

ValueError: operands could not be broadcast together with shapes (0,1) (2,1)

这是我感到困惑的地方 - 我认为这必须与我将i调用iloc的方式有关,因为当我手动计算它时我没有收到形状错误,就像在上面有4的示例。但是,看看其他示例和文档,我不明白为什么会这样......任何帮助都表示赞赏。

1 个答案:

答案 0 :(得分:2)

您的第一个问题是您正在尝试将两种不同大小的数组相乘。例如,当i=0 for循环的不同部分返回

df.iloc[max(1,(0-3)):0].values.shape
# (0,1)

w.iloc[-min(3,(0-1)):4].values.shape    
# (2,1)

这正是你得到的错误。我可以想到使数组可倍增的最简单方法是使用concatenation使用前导零填充数据帧。

df2 = pd.concat([pd.Series([0,0]),df], ignore_index=True)
df2
    0
0   0
1   0
2   0
3   1
4   2
5   3
6   4
7   5
8   6
9   7
10  8

虽然您现在可以使用for循环(稍微调整一下):

for i in range(len(df)):
    dot.loc[i] = sum(df2.iloc[max(0,(i)):i+3].values * w.values)

更好的方式可能就是JohnE suggested使用pandas内置的rollingapply函数的方式,通过摆脱你的for循环

import numpy as np
df2.rolling(3,min_periods=3).apply(lambda x: np.dot(x,w))
    0
0   NaN
1   NaN
2   0.00
3   0.50
4   1.25
5   2.10
6   2.95
7   3.80
8   4.65
9   5.50
10  6.35

您还可以drop前两个填充行和reset the index

df2.rolling(3,min_periods=3).apply(lambda x: np.dot(x,w)).drop([0,1]).reset_index(drop=True)
    0
0   0.00
1   0.50
2   1.25
3   2.10
4   2.95
5   3.80
6   4.65
7   5.50
8   6.35