按多层类别分组,并返回每个类别中n个最大的和(每个类别的n不同)

时间:2019-07-10 19:36:33

标签: python pandas pandas-groupby

我有一个熊猫数据框(df),代表不同个人的每月支出。数据框中的第一列是个人ID,第二列是费用类别,第三列是支出金额。请参见下面的示例表:

d = {'PersonID': ['A','A','A','A','A','A','A','A','B','B','B','B','B','B'], 'Category': ['Food','Food','Food','Food','Travel','Travel','Travel','Travel','Food','Food','Food','Travel','Travel','Travel'], 'Expenditure':[10,15,5,20,500,100,1000,2000,10,30,10,800,1000,400]}
df = pd.DataFrame(data=d)

enter image description here

对于每个人,我想获得食物类别中三项最大支出的总和,以及旅行类别中两项最大支出的总和。

对于上面的示例表,我需要下表:

enter image description here

我正在尝试使用以下代码,但问题是我无法在不同类别中指定不同的N大费用。

df.groupby(['PersonID','Category'])['Expenditure'].nlargest(2).sum(level=0)

1 个答案:

答案 0 :(得分:2)

要做的是先按类别划分数据框,然后按分组和,然后将结果串联在一起。

pd.concat([
df.query('Category == "Food"').groupby(['PersonID','Category'])['Expenditure'].nlargest(3).sum(level=[0,1]),
df.query('Category == "Travel"').groupby(['PersonID','Category'])['Expenditure'].nlargest(2).sum(level=[0,1])
])

输出:

PersonID  Category
A         Food          45
B         Food          50
A         Travel      3000
B         Travel      1800
Name: Expenditure, dtype: int64

使用字典和列表理解:

d = {'Food':2,
     'Travel':3}

pd.concat([df[df['Category'] == c].groupby(['PersonID','Category'])['Expenditure'].nlargest(n).sum(level=[0,1]) for c,n in d.items()])