简介及问题
如果排序基于多个列,并且排序允许并列排序,如何对组内的观察进行排序?
我知道如何使用groupby()
方法计算聚合的组级统计数据,我也知道如何使用多列不分组进行排名(参见here,here和here)。主要问题似乎是如何将这两种想法(分组和排名)很好地结合在一起。
This other thread对于如何解决这个问题有一些想法,但是它的结果并不显示哪些行是并列的--它只返回一个秩不断增加的数组,即使值是相同的。
最小可复制示例
import pandas as pd
df = pd.DataFrame({'row_id':[1,2,3,4,5,6,7,8,9,10],
'Group':[1,1,1,1,1,2,2,2,2,2],
'Var1':[100,100,100,200,200,300,300,400,400,400],
'Var2':[5,5,6,7,8,1,1,2,2,3]})
print(df)
# row_id Group Var1 Var2
# 0 1 1 100 5
# 1 2 1 100 5
# 2 3 1 100 6
# 3 4 1 200 7
# 4 5 1 200 8
# 5 6 2 300 1
# 6 7 2 300 1
# 7 8 2 400 2
# 8 9 2 400 2
# 9 10 2 400 3
在上面的例子中,我想使用Group
变量进行分组,并使用Var1
和Var2
变量进行排名。因此,我希望输出如下所示:
# row_id Group Var1 Var2 Rank
# 0 1 1 100 5 1
# 1 2 1 100 5 1
# 2 3 1 100 6 3
# 3 4 1 200 7 4
# 4 5 1 200 8 5
# 5 6 2 300 1 1
# 6 7 2 300 1 1
# 7 8 2 400 2 3
# 8 9 2 400 2 3
# 9 10 2 400 3 5
我所尝试的
使用上面示例中的数据,如果我想使用Group
变量进行分组,并且只基于Var1
列进行排名,这将非常容易:
df['Rank_Only_Var1'] = df.groupby('Group')['Var1'].rank(method='min', ascending=True)
print(df)
# row_id Group Var1 Var2 Rank_Only_Var1
# 0 1 1 100 5 1.0
# 1 2 1 100 5 1.0
# 2 3 1 100 6 1.0
# 3 4 1 200 7 4.0
# 4 5 1 200 8 4.0
# 5 6 2 300 1 1.0
# 6 7 2 300 1 1.0
# 7 8 2 400 2 3.0
# 8 9 2 400 2 3.0
# 9 10 2 400 3 3.0
然而,如果我想使用Group
变量进行分组,并使用Var1
和Var2
变量进行排名,事情就会变得棘手。使用by this other post建议的方法,我们得到以下结果:
df = df.sort_values(['Var1', 'Var1'], ascending=[True, True])
df['overall_rank'] = 1
df['overall_rank'] = df.groupby(['Group'])['overall_rank'].cumsum()
print(df)
# row_id Group Var1 Var2 overall_rank
# 0 1 1 100 5 1
# 1 2 1 100 5 2
# 2 3 1 100 6 3
# 3 4 1 200 7 4
# 4 5 1 200 8 5
# 5 6 2 300 1 1
# 6 7 2 300 1 2
# 7 8 2 400 2 3
# 8 9 2 400 2 4
# 9 10 2 400 3 5
请注意,第一行和第二行的Var1
和Var2
值相同,但第一行的排名为1,第二行的排名为2。这两行不应具有不同的排名。它们的排名应相同且并列。因为排名所基于的值是相同的并且是并列的。这个问题也发生在第6行和第7行以及第8行和第9行。
我甚至试着从this answer中修改解决方案,但当我们有groupby
语句时,它不起作用。
回到问题的核心
如果排序基于多个列,并且排序允许并列排序,如何对组内的观察进行排序?
1条答案
按热度按时间bfhwhh0e1#
不清楚为什么不能将链接解决方案与
.groupby
一起使用您也可以替换
.apply
以获得更好的性能: