如何在Pandas中分组和排名,同时排除一个组中的值?

1 投票
3 回答
37 浏览
提问于 2025-04-12 14:54

假设我有一个数据表,如下图所示,我想根据“日期”对分数进行排名,但不考虑每组的“总分”值。

下面的第二张图就是我希望得到的结果。

有没有什么高效的方法可以做到这一点呢?

data = pd.DataFrame({'Day':['Monday','Monday','Monday','Monday','Tuesday','Tuesday','Tuesday','Tuesday'],
                 'City':['NY','Chicago','Miami','Total','NY','Chicago','Miami','Total'],
                 'Score':[100,90,70,260,120,80,90,290]})

enter image description here

enter image description here

3 个回答

0

另一种可能的解决方案是使用 mask 函数,把 Total 这一列的 Score 设置为 NaN,然后再使用 rank 函数进行排名:

data['Rank'] = (
    data.assign(
        Score = data['Score'].mask(data['City'].eq('Total')))
    .groupby('Day')['Score']
    .rank(method='dense', ascending=False)
    )

输出结果:

       Day     City  Score  Rank
0   Monday       NY    100   1.0
1   Monday  Chicago     90   2.0
2   Monday    Miami     70   3.0
3   Monday    Total    260   NaN
4  Tuesday       NY    120   1.0
5  Tuesday  Chicago     80   3.0
6  Tuesday    Miami     90   2.0
7  Tuesday    Total    290   NaN
4

试试使用 rank 这个功能。

首先,先把包含“总计”的那些行过滤掉,然后用 .loc 来给剩下的行打排名。

data.loc[data['City'] != 'Total', 'Rank'] = data.loc[data['City'] != 'Total'].groupby('Day')['Score'].rank(method='max', ascending=False)


       Day     City  Score  Rank
0   Monday       NY    100   1.0
1   Monday  Chicago     90   2.0
2   Monday    Miami     70   3.0
3   Monday    Total    260   NaN
4  Tuesday       NY    120   1.0
5  Tuesday  Chicago     80   3.0
6  Tuesday    Miami     90   2.0
7  Tuesday    Total    290   NaN
5

查看那些不是“总计”的行,然后给这些行进行排名,最后把排名结果放到一个新的“Rank”列里。因为行的顺序还保留着,所以城市会得到正确的排名,而“总计”这几行会显示为NaN,也就是没有值。

data.loc[data['City'] != 'Total', 'Rank'] = data.loc[data['City'] != 'Total'].groupby('Day')['Score'].rank(ascending = False)

撰写回答