在Python中获取组间的累积平均值
我试图得到不同组之间python的累积平均值。 我有以下资料:在Python中获取组间的累积平均值,python,pandas,dataframe,Python,Pandas,Dataframe,我试图得到不同组之间python的累积平均值。 我有以下资料: id date value 1 2019-01-01 2 1 2019-01-02 8 1 2019-01-04 3 1 2019-01-08 4 1 2019-01-10 12 1 2019-01-13 6 2 2019-01-01 4 2 2019-01-03 2 2 2019-01-04 3 2 2019-01-06 6 2 2019-01-11
id date value
1 2019-01-01 2
1 2019-01-02 8
1 2019-01-04 3
1 2019-01-08 4
1 2019-01-10 12
1 2019-01-13 6
2 2019-01-01 4
2 2019-01-03 2
2 2019-01-04 3
2 2019-01-06 6
2 2019-01-11 1
我试图得到的输出如下:
id date value cumulative_avg
1 2019-01-01 2 NaN
1 2019-01-02 8 2
1 2019-01-04 3 5
1 2019-01-08 4 4.33
1 2019-01-10 12 4.25
1 2019-01-13 6 5.8
2 2019-01-01 4 NaN
2 2019-01-03 2 4
2 2019-01-04 3 3
2 2019-01-06 6 3
2 2019-01-11 1 3.75
我需要使用每个新id重新启动的累积平均值。
我可以用一个变量来获得我所寻找的变量,例如,如果数据集只有id=1的数据,那么我可以使用:
df['cumulative_avg'] = df['value'].expanding.mean().shift(1)
我尝试将group by添加到其中,但出现错误:
df['cumulative_avg'] = df.groupby('id')['value'].expanding().mean().shift(1)
TypeError: incompatible index of inserted column with frame index
还尝试:
df.set_index(['account']
ValueError: cannot handle a non-unique multi-index!
我拥有的实际数据有数百万行和数千个唯一ID’。如果您能以快速/高效的方式提供帮助,我们将不胜感激 在
groupby
之后,您无法真正链接方法,在您的示例中,shift
不再按组进行,因此您将无法获得预期的结果。无论如何,索引对齐都有问题,所以不能创建这样的列。因此,您可以:
df['cumulative_avg'] = df.groupby('id')['value'].apply(lambda x: x.expanding().mean().shift(1))
print (df)
id date value cumulative_avg
0 1 2019-01-01 2 NaN
1 1 2019-01-02 8 2.000000
2 1 2019-01-04 3 5.000000
3 1 2019-01-08 4 4.333333
4 1 2019-01-10 12 4.250000
5 1 2019-01-13 6 5.800000
6 2 2019-01-01 4 NaN
7 2 2019-01-03 2 4.000000
8 2 2019-01-04 3 3.000000
9 2 2019-01-06 6 3.000000
10 2 2019-01-11 1 3.750000
对于许多组,这将表现得更好,因为它省去了
apply
。取cumsum
除以cumcount
,减去该值,得到展开的模拟值。幸运的是,熊猫将0/0解释为NaN
gp = df.groupby('id')['value']
df['cum_avg'] = (gp.cumsum() - df['value'])/gp.cumcount()
id date value cum_avg
0 1 2019-01-01 2 NaN
1 1 2019-01-02 8 2.000000
2 1 2019-01-04 3 5.000000
3 1 2019-01-08 4 4.333333
4 1 2019-01-10 12 4.250000
5 1 2019-01-13 6 5.800000
6 2 2019-01-01 4 NaN
7 2 2019-01-03 2 4.000000
8 2 2019-01-04 3 3.000000
9 2 2019-01-06 6 3.000000
10 2 2019-01-11 1 3.750000
@Ben.T,不,通常情况下,它并没有那么糟糕,而且对于更复杂的聚合,或者甚至看起来像是将组内的基本方法链接在一起的简单聚合,通常需要一个groupby.apply
。但事实证明,这是一个缓慢的python级循环。因此,如果你发现自己处于一种情况,即你有5个组,每个组可能有5-10个观察值,这几乎和典型的数据帧一样慢。应用这里的主要加速来自于cumsum
和cumcount
,作为内置的GroupBy
聚合,转到更快的cython
分支进行计算。显然,所有的聚合都不能归结为像这样简单的数学,但如果可以的话,这是值得权衡的。你的解决方案更加直截了当和自我记录,所以在大多数情况下,我会同意这一点,在这种情况下,与300毫秒相比,3毫秒并没有真正的收益。谢谢你的解释:)@ALollz:这很出色:)+1