在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

我试图得到不同组之间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  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