【问题标题】:Select top 3 categories in each group after groupby in pandas dataframe在 pandas 数据框中的 groupby 之后选择每个组中的前 3 个类别
【发布时间】:2019-11-03 00:10:13
【问题描述】:

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

| 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),但不知何故,排序将负数视为最大的。此外,结果也脱离了分组。请问有什么帮助吗?谢谢!

【问题讨论】:

  • 你能从样本数据中添加预期的输出吗?什么是 X,P, W 值?
  • @jezrael 好的,抱歉,我意识到这很混乱。 X、P、W 只是类型属性的值。让我在示例中添加这些值
  • 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'], '金额': [2,5,-1,-10,-5,0,30,2]}
  • 你能解释一下but somehow the sort treats negative numbers as the biggest.吗?
  • @jezrael 抱歉,我搞混了,这是因为我正在按组键排序,如果我只按名称级别排序就可以了。

标签: python pandas dataframe pandas-groupby


【解决方案1】:

用途:

#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

【讨论】:

  • 好的,所以现在我将所有索引展平为具有三列 ["Name","Type","Amount"] 的 df,我仍然可以将它们转为 3 列 Type 1, Type 2、Type 3给出的一些名字只有2行或0行?
  • @AhSheng - 不确定是否理解,如果某些名称只有 012 值,那么解决方案工作得很好,只有不存在的值才会创建缺失值。跨度>
【解决方案2】:

我不能 100% 确定我是否正确理解了您的问题,但您可以使用

df.nlargest(5,["Amount"])

这将选择 5 个最大的金额。你可以调整5。

【讨论】:

  • 这太棒了!好的,它给了我前 5 名,但有些名称只有前 3 名,但我需要将这些值转换为 5 个新列(即类型 1、类型 2、类型 3、类型 4、类型 5)。
  • 我目前没有时间检查如何执行此操作,而且我对 Python 还比较陌生。对不起!如果我在白天找到一些时间,我会检查它。也许@jezrael 知道如何在这种情况下做到这一点?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-12
  • 2021-06-14
  • 2018-05-22
  • 2023-04-02
  • 2012-07-29
  • 2019-06-24
相关资源
最近更新 更多