从熊猫数据框中选择排序组的第一行

Posted

技术标签:

【中文标题】从熊猫数据框中选择排序组的第一行【英文标题】:Selecting the first row of a sorted group from pandas data frame 【发布时间】:2017-06-30 01:53:40 【问题描述】:

假设,我在 pandas 中有一个如下所示的数据框:

campaignname    category_type    amount
A               cat_A_0            2.0
A               cat_A_1            1.0
A               cat_A_2            3.0
A               cat_A_2            3.0
A               cat_A_2            4.0
B               cat_B_0            3.0
C               cat_C_0            1.0
C               cat_C_1            2.0

我正在使用以下代码将上述数据框(例如分配了变量名df)按不同的列分组,如下所示:

for name, gp in df.groupby('campaignname'):
    sorted_gp = gp.groupby(['campaignname', 'category_type']).sum().sort_values(['amount'], ascending=False)
    # I'd like to know how to select this in a cleaner/more concise way
    first_row = [sorted_gp.iloc[0].name[0], sorted_gp.iloc[0].name[1], sorted_gp.iloc[0].values.tolist()[0]]

上述代码的目的是首先groupbycampaignname 列上的原始数据,然后在每个结果组中,我想再次按campaignnamecategory_type 进行分组,并且最后,按amount 列排序以选择出现的第一行(每组中amount 最高的行。特别是对于上面的示例,我想得到这样的结果:

first_row = ['A', 'cat_A_2', 4.0] # for the first group
first_row = ['B', 'cat_B_0', 3.0] # for the second group
first_row = ['C', 'cat_C_1', 2.0] # for the third group

等等

如您所见,我正在使用一种相当(在我看来)“丑陋”的方式来检索每个排序组的第一行,但是由于我是 pandas 的新手,所以我不知道更好/更清洁的方法来实现这一点。如果有人可以让我知道一种从熊猫数据框中选择排序组中第一行的方法,我将不胜感激。提前感谢您的回答/建议!

【问题讨论】:

【参考方案1】:

IIUC 你可以这样做:

In [83]: df.groupby('campaignname', as_index=False) \
           .apply(lambda x: x.nlargest(1, columns=['amount'])) \
           .reset_index(level=1, drop=1)
Out[83]:
  campaignname category_type  amount
0            A       cat_A_2     4.0
1            B       cat_B_0     3.0
2            C       cat_C_1     2.0

或:

In [76]: df.sort_values('amount', ascending=False).groupby('campaignname').head(1)
Out[76]:
  campaignname category_type  amount
4            A       cat_A_2     4.0
5            B       cat_B_0     3.0
7            C       cat_C_1     2.0

【讨论】:

感谢您的建议。但是当我运行你建议的代码时,它仍然返回整个数据框,但按分组和排序。我想要的是迭代组,根据数量在每个组内排序,仅迭代地选择每个组中排序结果的顶行。我想我的问题太模糊了,也许我应该修改它......【参考方案2】:

我首选的方法是使用idxmax。它返回最大值的索引。我随后使用该索引对df进行切片

df.loc[df.groupby('campaignname').amount.idxmax()]

  campaignname category_type  amount
4            A       cat_A_2     4.0
5            B       cat_B_0     3.0
7            C       cat_C_1     2.0

【讨论】:

感谢您的建议。但是当我运行你建议的代码时,它仍然返回整个数据框,但按分组和排序。我想要的是遍历组,根据amount 在每个组中排序,选择排序结果的第一行。我想我的问题太模糊了,也许我应该修改它...... @user1330974 这应该返回您要求的相同内容。在每个组中排序后的第一行。我发布的内容显示了你会得到什么,这就是你所要求的。 运行df.loc[df.groupby('campaignname').amount.idxmax()]后,我仍然看到数据框中的所有行...谢谢您的帮助!

以上是关于从熊猫数据框中选择排序组的第一行的主要内容,如果未能解决你的问题,请参考以下文章

从熊猫数据框中的组内选择特定行

如何根据多个排序列选择每组的第一行?

在熊猫多索引数据框中返回满足逻辑索引条件的每个组的最后一行[重复]

在熊猫数据框中查找上一个组的名称

如何将熊猫数据框值除以每组的第一行?

Python Pandas数据框中的行排序/计数