基于Pandas分组 按Col2排名保留第2、3位数据
解决Pandas分组保留每组指定排名行的问题
嘿,这个需求很常见,咱们用Pandas几步就能搞定,先给你完整的可运行代码,再拆解每一步~
首先,先构造你提供的原始DataFrame:
import pandas as pd # 初始化原始数据 df = pd.DataFrame({ 'Col1': ['a', 'a', 'a', 'a', 'b', 'b'], 'Col2': [8, 3, 1, 0, 6, 2], 'Col3': [9, 7, 3, 8, 18, 6] })
方法一:分组排序后取指定位置行
这是最直观的方式,先分组、再排序、最后提取目标行:
# 按Col1分组,每组按Col2降序排序,提取第2、3名(对应索引1和2,0-based) result = df.groupby('Col1', group_keys=False).apply( lambda x: x.sort_values('Col2', ascending=False).iloc[1:3] ).reset_index(drop=True) print(result)
运行后输出就是你要的结果:
Col1 Col2 Col3 0 a 3 7 1 a 1 3 2 b 2 6
步骤拆解:
groupby('Col1', group_keys=False):按Col1分组,group_keys=False可以避免结果里自动添加分组键作为索引,让输出更清爽。x.sort_values('Col2', ascending=False):对每个分组内的数据按Col2降序排序,这样最大的数值排在最前面(对应排名第1)。iloc[1:3]:提取排序后索引为1和2的行,也就是每组的第2、3名。如果分组的行数不足3(比如示例中的b组只有2行),会自动只提取存在的符合条件的行。reset_index(drop=True):重置结果的索引,让索引从0开始连续排列。
方法二:用rank函数筛选排名行
如果你需要先计算排名再筛选,可以用这种方式:
# 计算每组内Col2的降序排名 df['rank'] = df.groupby('Col1')['Col2'].rank(ascending=False, method='first') # 筛选排名为2和3的行,去掉rank列并重置索引 result = df[df['rank'].isin([2, 3])].drop('rank', axis=1).reset_index(drop=True)
这个方法的核心是rank函数:
ascending=False表示按降序排名,数值越大排名越靠前。method='first'保证遇到相同值时,按数据出现的顺序排名,避免并列排名导致的筛选偏差。
两种方法都能得到你想要的结果,按需选择就行~
内容的提问来源于stack exchange,提问作者NBC
相关产品推荐
相关产品推荐

