在pandas中,如何将groupby聚合的结果分配给原始数据框中的下一组?

5
使用 pandas,我喜欢使用 groupby 和聚合函数(例如平均值),然后将结果放回原始数据框中下一个组而不是当前组。如何以向量化的方式实现?
我有一个如下所示的 pandas 数据框:
data = {'Group': ['A','A','B','B','B','B', 'C','C', 'D','D'],
        'Value': [1.1,1.3,9.1,9.2,9.5,9.4,6.2,6.4,2.2,2.3]
        }

df = pd.DataFrame(data, columns = ['Group','Value'])

print (df)

  Group  Value
0     A    1.1
1     A    1.3
2     B    9.1
3     B    9.2
4     B    9.5
5     B    9.4
6     C    6.2
7     C    6.4
8     D    2.2
9     D    2.3

我希望能够得到这样的结果,即每个组都包含前一组的平均值。

  Group  Value
0     A    NaN
1     A    NaN
2     B    1.2
3     B    1.2
4     B    1.2
5     B    1.2
6     C    9.3
7     C    9.3
8     D    6.3
9     D    6.3

我尝试了这个,但是没有切换到下一组。
df.groupby('Group')['Value'].transform('mean')
2个回答

7

简单地使用 map 在一个 groupby 结果上:

df['Value'] = df['Group'].map(df.groupby('Group')['Value'].mean().shift()) 
df
  Group  Value
0     A    NaN
1     A    NaN
2     B    1.2
3     B    1.2
4     B    1.2
5     B    1.2
6     C    9.3
7     C    9.3
8     D    6.3
9     D    6.3

工作原理

获取平均值

df.groupby('Group')['Value'].mean()

Group
A    1.20
B    9.30
C    6.30
D    2.25
Name: Value, dtype: float64

将其向下移动1个单位

df.groupby('Group')['Value'].mean().shift() 

Group
A    NaN
B    1.2
C    9.3
D    6.3
Name: Value, dtype: float64

映射回去。

df['Group'].map(df.groupby('Group')['Value'].mean().shift())  

0    NaN
1    NaN
2    1.2
3    1.2
4    1.2
5    1.2
6    9.3
7    9.3
8    6.3
9    6.3
Name: Group, dtype: float64

谢谢,太棒了。比我的应用解决方案快得多。 - rudi2013
如果你的解决方案使用了apply,那么我的可能更快;) - cs95
根据计时分析,你的解决方案比我的快1.6倍。我猜这是由于.set_index.reset_index使我的答案变慢了。 - Ch3steR
1
@Ch3steR 感谢你花费时间!尝试重新进行计时,不要使用 set 和 reset 索引调用,速度可能会更快。通过这种方式,您可以尝试说服 OP 使用该特定列作为索引,因为它会导致更快,更优化的代码。有时这些小的权衡是值得的。 - cs95

3
你可以计算每个分组值的聚合GroupBy.mean,并使用pd.Series.shift,利用 Pandas 索引对齐。
df.set_index('Group').assign(value = df.groupby('Group').mean().shift()).reset_index()

  Group  Value  value
0     A    1.1    NaN
1     A    1.3    NaN
2     B    9.1    1.2
3     B    9.2    1.2
4     B    9.5    1.2
5     B    9.4    1.2
6     C    6.2    9.3
7     C    6.4    9.3
8     D    2.2    6.3
9     D    2.3    6.3

让pandas Index.map自动处理映射是一个不错的点子。 (+1) 不要忘记加上.reset_index(),因为OP可能不想要Group index。 - cs95
谢谢 @cs95。添加 .reset_indexpd.Series.map同样好用和高效(已经点赞了)。 - Ch3steR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接