我对python还比较陌生,我一直在尝试在熊猫数据框架中计算跨行的简单滚动加权平均数。我有一个观测df的数据和一个权重w的数据。我创建了一个新的dataframe来保存这两组值( 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的例子一样。但是,看看其他的例子和文档,我不明白为什么会这样.任何帮助都是非常感谢的。
发布于 2017-12-09 23:01:47
您的第一个问题是,您试图将两个不同大小的数组相乘。例如,当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)这正是你所犯的错误。我能想到的使数组可乘的最简单方法是用前导零填充数据,使用串连。
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 建议,通过去掉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.35df2.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.35https://stackoverflow.com/questions/47732567
复制相似问题