如何在Python DataFrame各列提取前3大值对应的ID列表?含等值处理
提取DataFrame每列Top3数值对应ID(含并列场景处理)
嗨,很高兴能帮到你!针对你提出的提取DataFrame每列中3个最大数值对应ID的需求,我整理了两种实用的处理方案,专门覆盖了数值相等的场景,一起来看看:
先构造示例DataFrame(方便演示)
首先我们先模拟一个包含并列数值的DataFrame,和你提到的第三轮场景类似:
import pandas as pd # 构造示例数据,ID为索引,包含多组并列数值 data = { 'ID': ['A', 'B', 'C', 'D', 'E', 'F'], '第一轮': [10, 25, 25, 15, 30, 20], '第二轮': [5, 18, 18, 22, 18, 25], '第三轮': [40, 40, 35, 35, 20, 10] } df = pd.DataFrame(data).set_index('ID')
方案1:保留所有并列的Top3数值对应ID
如果你的需求是只要数值属于前3大的范围,所有对应的ID都要保留(比如第三轮的两个40、两个35都要提取),可以用这个方法:
def get_top_ids(column, top_n=3): # 对列按数值降序排序(mergesort保证排序稳定性) sorted_col = column.sort_values(ascending=False, kind='mergesort') # 提取前top_n个唯一的最大数值 top_values = sorted_col.unique()[:top_n] # 返回所有匹配这些数值的ID列表 return sorted_col[sorted_col.isin(top_values)].index.tolist() # 把函数应用到每一列 top_ids_result = df.apply(get_top_ids) print(top_ids_result)
输出示例:
第一轮 [E, B, C] 第二轮 [F, D, B, C, E] 第三轮 [A, B, C, D] dtype: object
可以看到,第二轮中数值18属于第三大的数值,所有对应的ID都被保留了;第三轮的两个40、两个35也全部被提取。
方案2:严格提取最多3个ID(忽略多余并列)
如果你的需求是不管并列情况,只取最多3个ID,可以用nlargest方法,通过keep参数控制并列值的取舍:
def get_strict_top_ids(column, top_n=3): # keep='first':遇到并列时保留最先出现的ID;可选keep='last'保留最后出现的 return column.nlargest(top_n, keep='first').index.tolist() # 应用到每一列 strict_top_ids_result = df.apply(get_strict_top_ids) print(strict_top_ids_result)
输出示例:
第一轮 [E, B, C] 第二轮 [F, D, B] 第三轮 [A, B, C] dtype: object
这里第二轮只取了前3个ID(F、D、B),忽略了后面并列的C和E;第三轮取了前3个ID(A、B、C)。
特殊情况:ID是普通列而非索引
如果你的DataFrame中ID是单独的列(不是索引),只需要稍微调整代码即可:
def get_top_ids_from_col(column, df, top_n=3): # 按当前列降序排序 sorted_df = df.sort_values(by=column.name, ascending=False, kind='mergesort') # 提取前top_n个唯一数值 top_values = sorted_df[column.name].unique()[:top_n] # 返回对应的ID列表 return sorted_df[sorted_df[column.name].isin(top_values)]['ID'].tolist() # 应用到每一列(排除ID列) top_ids_result = df.drop('ID', axis=1).apply(lambda col: get_top_ids_from_col(col, df))
如果你的DataFrame结构和示例有差异,或者还有其他特殊需求,随时告诉我,我再帮你调整代码~
内容的提问来源于stack exchange,提问作者galanonim
相关产品推荐
相关产品推荐

