如何在Pandas中分组和排名,同时排除一个组中的值?
假设我有一个数据表,如下图所示,我想根据“日期”对分数进行排名,但不考虑每组的“总分”值。
下面的第二张图就是我希望得到的结果。
有没有什么高效的方法可以做到这一点呢?
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]})
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)