熊猫分组总和

Posted

技术标签:

【中文标题】熊猫分组总和【英文标题】:Pandas groupby sum 【发布时间】:2017-02-06 14:46:57 【问题描述】:

我有一个如下的数据框:

ref, type, amount
001, foo, 10
001, foo, 5
001, bar, 50
001, bar, 5
001, test, 100
001, test, 90
002, foo, 20
002, foo, 35
002, bar, 75
002, bar, 80
002, test, 150
002, test, 110

这就是我想要得到的:

ref, type, amount, foo, bar, test
001, foo, 10, 15, 55, 190
001, foo, 5, 15, 55, 190
001, bar, 50, 15, 55, 190
001, bar, 5, 15, 55, 190
001, test, 100, 15, 55, 190
001, test, 90, 15, 55, 190
002, foo, 20, 55, 155, 260
002, foo, 35, 55, 155, 260
002, bar, 75, 55, 155, 260
002, bar, 80, 55, 155, 260
002, test, 150, 55, 155, 260
002, test, 110, 55, 155, 260

所以我有这个:

df.groupby('ref')['amount'].transform(sum)

但是我如何过滤它以使上述内容仅适用于 type=foobartest 的行?

【问题讨论】:

@EdChum 是的,我可以过滤数据框,但我需要三个新列,其中 ref 和 type 的总和为“amount”。如果这有意义? 那么为什么不在 ref 上进行 groupby 然后输入呢? 我可以对 ref 和 type 进行分组,但列如何工作?因为我想要每个类型值的总和。 我想我误解了你所追求的,你需要使用 mapmerge 与原始 df 的结果聚合 【参考方案1】:

我认为你需要groupbyunstack 然后merge 到原来的DataFrame

df1 = df.groupby(['ref','type'])['amount'].sum().unstack().reset_index()
print (df1)
type  ref  bar  foo  test
0     001   55   15   190
1     002  155   55   260

df = pd.merge(df, df1, on='ref')
print (df)
    ref  type  amount  sums  bar  foo  test
0   001   foo      10    15   55   15   190
1   001   foo       5    15   55   15   190
2   001   bar      50    55   55   15   190
3   001   bar       5    55   55   15   190
4   001  test     100   190   55   15   190
5   001  test      90   190   55   15   190
6   002   foo      20    55  155   55   260
7   002   foo      35    55  155   55   260
8   002   bar      75   155  155   55   260
9   002   bar      80   155  155   55   260
10  002  test     150   260  155   55   260
11  002  test     110   260  155   55   260

时间安排

In [506]: %timeit (pd.merge(df, df.groupby(['ref','type'])['amount'].sum().unstack().reset_index(), on='ref'))
100 loops, best of 3: 3.4 ms per loop

In [507]: %timeit (pd.merge(df, pd.pivot_table(df, values='amount', index=['ref'], columns=['type'], aggfunc=np.sum), left_on='ref', right_index=True))
100 loops, best of 3: 4.99 ms per loop

【讨论】:

这正是我所需要的。非常感谢! 很高兴能帮到你!【参考方案2】:

使用pivot table 的解决方案:

>>> b = pd.pivot_table(df, values='amount', index=['ref'], columns=['type'], aggfunc=np.sum)
>>> b
type  bar  foo  test
ref
1      55   15   190
2     155   55   260

>>> pd.merge(df, b, left_on='ref', right_index=True)
    ref  type  amount  bar  foo  test
0     1   foo      10   55   15   190
1     1   foo       5   55   15   190
2     1   bar      50   55   15   190
3     1   bar       5   55   15   190
4     1  test     100   55   15   190
5     1  test      90   55   15   190
6     2   foo      20  155   55   260
7     2   foo      35  155   55   260
8     2   bar      75  155   55   260
9     2   bar      80  155   55   260
10    2  test     150  155   55   260
11    2  test     110  155   55   260

【讨论】:

以上是关于熊猫分组总和的主要内容,如果未能解决你的问题,请参考以下文章

相邻行熊猫的分组条件总和

熊猫按时间和分组滚动条件总和

熊猫:设置列等于另一列的分组总和[重复]

按一列分组并在熊猫中找到另一列的总和和最大值

大熊猫中分组的条件比率

按多列分组时熊猫组合键