You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas groupby后nlargest性能优化及获取第二大值行的技术咨询

高效解决Pandas分组排序取前N行及指定行的问题

针对你遇到的apply方法处理大量分组时速度慢的问题,以及只取每组第二行的需求,这里给出两个高效的解决方案——都是基于Pandas的向量化操作,比逐组apply快得多:


一、替代apply快速获取每组前2行

apply慢的核心原因是它会对每个分组单独执行函数,在分组数量多的时候,循环开销极大。更高效的思路是先整体排序,再分组取头部——Pandas的sort_values和groupby.head都是经过优化的批量操作,性能提升非常明显:

# 先按Date保持原顺序,再按OI降序排序(确保每组内OI从大到小排列)
df_sorted = df.sort_values(['Date', 'OI'], ascending=[True, False])
# 分组后取每组前2行,sort=False保留原数据的分组顺序
top2 = df_sorted.groupby('Date', sort=False).head(2)

这个方法的时间复杂度远低于apply,尤其是当分组数超过1000时,速度差距会非常显著。


二、仅获取每组按OI排序后的第二行

如果只需要每组的第二行(即降序排序后的第2个元素),推荐两种可靠的实现方式:

方法1:排序后用groupby.nth()

利用nth()直接提取分组内指定位置的行(索引从0开始,所以第二行对应nth(1)):

# 先按Date和OI降序排序
df_sorted = df.sort_values(['Date', 'OI'], ascending=[True, False])
# 取每组第二行,dropna=False可选,用于保留组内不足2行的分组(会返回NaN)
second_row = df_sorted.groupby('Date', sort=False, dropna=False).nth(1)

方法2:用rank()标记排名后筛选

如果需要处理OI有重复值的场景,可以用rank()给每组内的OI标记排名,再筛选排名为2的行:

# 按Date分组,对OI降序排名,method='first'确保相同OI的行有唯一排名
df['oi_rank'] = df.groupby('Date')['OI'].rank(ascending=False, method='first')
# 筛选排名为2的行,最后删除临时的排名列
second_row = df[df['oi_rank'] == 2].drop('oi_rank', axis=1)

如果业务允许相同OI的行共享排名,可以把method='first'换成method='min',但这种情况下可能会出现多行排名为2的情况,需要根据你的需求调整。


内容的提问来源于stack exchange,提问作者Z.G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:24:50