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

如何获取DataFrame列中第2/3大值的索引(Python)

获取DataFrame每列第N大值的索引(类似idxmax()的功能)

需求说明

需要获取DataFrame每列中第二大值对应的行索引,实现和idxmax()类似但针对第N大值的功能。目前已能通过col.nlargest(2).values[-1]获取第二大值,但需要对应的索引位置。

现有代码及输出

生成测试数据并获取第2、3大值的代码:

import pandas as pd
import numpy as np

test_2ndmax = pd.DataFrame({'Col{}'.format(i):np.random.randint(0,100,5) for i in range(5)})
display(test_2ndmax)

# 获取每列第二大值
display(test_2ndmax.apply(lambda col: col.nlargest(2).values[-1],axis=0))

# 获取每列第三大值
display(test_2ndmax.apply(lambda col: col.nlargest(3).values[-1],axis=0))

对应输出:

Col0    Col1    Col2    Col3    Col4
0   9       15      24      45      85
1   26      50      91      34      60
2   3       88      84      17      53
3   8       58      73      56      11
4   82      65      93      3       46

Col0    82
Col1    65
Col2    91
Col3    45
Col4    60
dtype: int32

Col0    26
Col1    58
Col2    84
Col3    34
Col4    53
dtype: int32

期望得到类似idxmax()的索引输出(以第二大值为例):

Col0    4
Col1    4
Col2    1
Col3    0
Col4    1

解决方案

方法1:直接利用nlargest()的索引

修改apply中的逻辑,直接提取nlargest()返回结果的最后一个索引即可:

# 获取每列第二大值的索引
test_2ndmax.apply(lambda col: col.nlargest(2).index[-1], axis=0)

# 获取每列第三大值的索引
test_2ndmax.apply(lambda col: col.nlargest(3).index[-1], axis=0)

针对示例数据,第二大值索引的输出与期望完全一致:

Col0    4
Col1    4
Col2    1
Col3    0
Col4    1
dtype: int64

方法2:用argsort()实现高效批量处理

如果数据量较大,argsort()的性能更优,通过对列进行降序排序后取对应位置的索引:

# 获取第二大值的索引
test_2ndmax.apply(lambda col: col.argsort(ascending=False)[1], axis=0)

# 获取第三大值的索引
test_2ndmax.apply(lambda col: col.argsort(ascending=False)[2], axis=0)

该方法结果与nlargest()一致,当列中存在重复值时,会返回重复值里位置靠后的索引,和nlargest()行为保持统一。

重复值处理说明

如果某列存在多个相同的第N大值,nlargest(N)会包含所有等于该值的行,此时index[-1]会取该值对应的最后一个索引。若需要第一个出现的索引,可改用:

test_2ndmax.apply(lambda col: col[col == col.nlargest(2).values[-1]].index[0], axis=0)

内容的提问来源于stack exchange,提问作者doudinette

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 22:25:48