如何获取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
相关产品推荐
相关产品推荐

