分组数据框并获得总和和计数?


79

我有一个看起来像这样的数据框:

              Company Name              Organisation Name  Amount
10118  Vifor Pharma UK Ltd  Welsh Assoc for Gastro & Endo 2700.00
10119  Vifor Pharma UK Ltd    Welsh IBD Specialist Group,  169.00
10120  Vifor Pharma UK Ltd             West Midlands AHSN 1200.00
10121  Vifor Pharma UK Ltd           Whittington Hospital   63.00
10122  Vifor Pharma UK Ltd                 Ysbyty Gwynedd   75.93

如何求和Amount并计算Organisation Name,以得到一个看起来像这样的新数据框?

              Company Name             Organisation Count   Amount
10118  Vifor Pharma UK Ltd                              5 11000.00

我知道如何求和计数:

df.groupby('Company Name').sum()
df.groupby('Company Name').count()

但不是两者都要做!

Answers:


143

试试这个:

In [110]: (df.groupby('Company Name')
   .....:    .agg({'Organisation Name':'count', 'Amount': 'sum'})
   .....:    .reset_index()
   .....:    .rename(columns={'Organisation Name':'Organisation Count'})
   .....: )
Out[110]:
          Company Name   Amount  Organisation Count
0  Vifor Pharma UK Ltd  4207.93                   5

或者如果您不想重置索引:

df.groupby('Company Name')['Amount'].agg(['sum','count'])

要么

df.groupby('Company Name').agg({'Amount': ['sum','count']})

演示:

In [98]: df.groupby('Company Name')['Amount'].agg(['sum','count'])
Out[98]:
                         sum  count
Company Name
Vifor Pharma UK Ltd  4207.93      5

In [99]: df.groupby('Company Name').agg({'Amount': ['sum','count']})
Out[99]:
                      Amount
                         sum count
Company Name
Vifor Pharma UK Ltd  4207.93     5

2
@MaxU有一种方法可以将总和和计数应用于不同但多个的同伴。当我尝试将列作为这样的列表给出时:agg({['hotel_name','hotel_country']:'count',['cost','revenue','clicks']:'sum'}) “ TypeError:无法散列的类型:'列表'”错误
CanCeylan

@CanCeylan不知道是否有可能在groupby子句中做到这一点,但您可以通过在数据帧中预先添加一个虚拟计数列然后再进行groupby sum来实现:df['count'] = 1
Karl Anka

1
最终,经过2小时的搜索操作,这只是第三个选项:df.groupby('Company Name')。agg({'Amount':['sum','count']})对我有用。
charo

嗨,谢谢您提供的出色解决方案。在我的特殊情况下,我在两个不同的列上使用您的解决方案来获取总和并计算行数。不幸的是,我得到了两倍的行数(ofc。因为它对两列都计数)。有没有一种方法可以删除一个.counts,这样我的表看起来很干净?df.groupby(df['L2 Name'])[["Amount arrear","VSU"]].agg(['sum','count'])
MLAlex

17

以防万一您想知道如何在聚合期间重命名列,以下是用于

大熊猫> = 0.25:命名聚合

df.groupby('Company Name')['Amount'].agg(MySum='sum', MyCount='count')

要么,

df.groupby('Company Name').agg(MySum=('Amount', 'sum'), MyCount=('Amount', 'count'))

                       MySum  MyCount
Company Name                       
Vifor Pharma UK Ltd  4207.93        5

这应该是例外的答案,有没有办法用新的更好的做事方式来更新旧问题/答案?排除的答案没有错,只是不再是最好的方法。
JSharm

@JSharm显然,您无法改变OP的想法,但是您可以肯定您认为最有价值的帖子。如果有足够多的人以与您相同的方式思考和采取行动,我们将有一天到达那里;)PS不要在公认的答案上加阴影,只要熊猫继续支持该语法,我仍然认为这是此问题的最佳答案,我有足够的信心相信它会持续很长一段时间。
cs95

3

如果您有很多列,但只有一个不同,则可以执行以下操作:

In[1]: grouper = df.groupby('Company Name')
In[2]: res = grouper.count()
In[3]: res['Amount'] = grouper.Amount.sum()
In[4]: res
Out[4]:
                      Organisation Name   Amount
Company Name                                   
Vifor Pharma UK Ltd                  5  4207.93

请注意,然后可以根据需要重命名“组织名称”列。


1
df.groupby('Company Name').agg({'Organisation name':'count','Amount':'sum'})\
    .apply(lambda x: x.sort_values(['count','sum'], ascending=False))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.