我有这个数据框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
感谢您的帮助!
答案 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