在熊猫问题中基于列值聚合行

时间:2020-10-12 19:06:36

标签: python python-3.x pandas pandas-groupby aggregate

我有这个数据框df

import numpy as np
import pandas as pd
df = pd.DataFrame({'name':['A','A','B','B','C','C'], 'year': ['2013','2013','2014','2014', '2015','2015'],
    'type': ['a', 'b', 'a', 'b', 'a', 'b'],
    'cost': [30, 15, 20, 15, 30,25]})

df

   name year    type    cost
0   A   2013    a       30
1   A   2013    b       15
2   B   2014    a       20
3   B   2014    b       15
4   C   2015    a       30
5   C   2015    b       25

我想获得每个名称的a和b的总数,因此每个名称将有一个第三行,看起来像这样。 我想要的数据框:


  name  year    type        cost
0   A   2013    a           30
1   A   2013    b           15
2   A   2013    total_ab    45
3   B   2014    a           20
4   B   2014    b           15
5   B   2014    total_ab    35
6   C   2015    a           30
7   C   2015    b           25
8   C   2015    total_ab    55

我已经尝试过了,无法完全达到我想要的结果。

dft=df.groupby(['name', 'year']).agg({'cost': 'sum'}).reset_index()
#dft= df.groupby(['name', 'year', 'type']).agg({'cost': 'sum'})
Out:


  name  year    cost
0   A   2013    45
1   B   2014    35
2   C   2015    55

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

不确定是否有直接的解决方案,但是您可以通过以下两个单独的操作对groupby和concat进行

更新:我也将year列添加到分组依据。

rows_to_add = df[df.type.isin(['a', 'b'])]\
         .groupby(['name','year'], as_index=False)['cost'].sum()\
        .assign(type='total_ab')

连接(并按照您的建议对名称进行排序)

df = pd.concat([df, rows_to_add]).sort_values(['name'])

此外,如果除df[df.type.isin(['a', 'b'])]a之外没有其他类型,则可以排除b部分

答案 1 :(得分:1)

您可以使用.groupby创建一个具有总计的新数据框,并将其附加。我还使总行的名称动态化为每个组中type列中的值。该答案假定您无需按照示例中的示例进行分组type

import numpy as np
import pandas as pd
df = pd.DataFrame({'name':['A','A','B','B','C','C'], 'year': ['2013','2013','2014','2014', '2015','2015'],
    'type': ['a', 'b', 'a', 'b', 'a', 'b'],
    'cost': [30, 15, 20, 15, 30,25]})

df1 = df.groupby(['name', 'year'], as_index=False).agg({'type' : lambda x: list(x), 'cost' : 'sum'})
df1['type'] = 'total_' + df1['type'].map(''.join)
df = df.append(df1).sort_values(['name', 'year', 'type'])
df
Out[1]: 
  name  year      type  cost
0    A  2013         a    30
1    A  2013         b    15
0    A  2013  total_ab    45
2    B  2014         a    20
3    B  2014         b    15
1    B  2014  total_ab    35
4    C  2015         a    30
5    C  2015         b    25
2    C  2015  total_ab    55