首页 > 解决方案 > 在 pandas 数据框中的 groupby 之后选择每个组中的前 3 个类别

问题描述

所以我的数据框现在看起来像这样:

| Name | Type | Class   | Amount |
|------|------|---------|--------|
| Abel | A    | Chinese | 2      |
| Abel | B    | English | 5      |
| Abel | C    | Science | -1     |
| Abel | D    | Physics | -10    |
| Cain | C    | Chinese | -5     |
| Cain | B    | Science | 0      |
| Cain | A    | English | 30     |
| Cain | D    | Chinese | 2      |
|------|------|---------|--------|

数据样本:

data = {'Name': ['Abel', 'Abel', 'Abel', 'Abel', 'Cain', 'Cain', 'Cain', 'Cain'],
'Type': ['A', 'B', 'C', 'D', 'C', 'B', 'A', 'D'],
'Class': ['Chinese', 'English', 'Science', 'Physics', 'Chinese', 'Science', 'English', 'Chinese'],
'Amount': [2,5,-1,-10,-5,0,30,2]}

我试图根据数量为每个名称查找前 n 类和前 n 类。

我尝试了 df.groupby(["Name","Type"]).sum() ,它给了我分组但我如何选择前 5 个以便我可以将它们转换为 5 个不同的列?

例如,前 3 种类型的最终输出应该是这样的,前 3 类只是类似的东西,除了列是第 1 类到第 3 类:

| Name | Type 1 | Type 2 | Type 3 |
|------|--------|--------|--------|
| Abel | B      |   A    |   C    |
| Cain | A      |   D    |   B    |

我尝试了 sort_values 然后 .head(5) ,但不知何故,排序将负数视为最大的。此外,结果也脱离了分组。请问有什么帮助吗?谢谢!

标签: pythonpandasdataframepandas-groupby

解决方案


利用:

#sorting by both columns
df1 = df.sort_values(['Name','Amount'], ascending=[True, False])
#create counter column used for later columns names
df1['g'] = df1.groupby('Name').cumcount().add(1)
#filter top3
df1 = df1[df1['g'] <= 3]
#reshape by pivot
df2 = df1.pivot('Name','g','Type').add_prefix('Type ').reset_index().rename_axis(None, axis=1)
print (df2)
   Name Type 1 Type 2 Type 3
0  Abel      B      A      C
1  Cain      A      D      B

推荐阅读