按行对多级列DataFrame指定列(b_1)降序排名的实现方案
最优方案:直接在原DataFrame中添加排名结果
直接在原表中生成并添加排名列是更高效的选择,无需拆分再合并,代码简洁且完全支持后续新增行/列的动态扩展。
实现步骤
- 提取所有二级列为
b_1的列:利用多级列的xs方法,不管后续新增多少一级列,只要二级列是b_1,都能自动匹配提取。 - 按行从大到小排名:使用
rank方法,指定按行计算、降序排列,可根据需求选择排名规则(比如相同值的处理方式)。 - 将排名结果作为新的多级列插入原表:保持列结构一致性,方便后续维护。
完整代码示例
import pandas as pd import numpy as np # 原始数据生成代码 level_2 = ['a_1', 'b_1', 'c_1', 'a_1', 'b_1', 'c_1', 'a_1', 'b_1', 'c_1'] level_1 = ['A1', 'A1', 'A1', 'B1', 'B1', 'B1', 'C1', 'C1', 'C1'] data = [['a', 23, 'h', 'o', 45, 'v', 'a3', 1, 'b1'], ['b', 34, 'i', 'p', 3, 'w', 'a4', 32, 'b2'], ['c', 5, 'j', 'q', 7, 'x', 'a5', 6, 'b3'], ['d', 2, 'k', 'r', 5, 'y', 'a6', 76, 'b4'], ['e', 78, 'l', 's', 65, 'z', 'a7', 9, 'b5'], ['f', 98, 'm', 't', 23, 'a1', 'a8', 14, 'b6'], ['g', 3, 'n', 'u', 1, 'a2', 'a9', 45, 'b7']] columns = pd.MultiIndex.from_tuples(list(zip(level_1, level_2))) df1 = pd.DataFrame(data, columns=columns) date = ['1/1/2023','1/2/2023','1/3/2023','1/4/2023','1/5/2023','1/6/2023','1/7/2023'] df1.insert(0, 'date', date) df1.set_index('date', inplace=True) # 核心排名代码 # 提取所有b_1列(自动适配所有一级列下的b_1) b1_cols = df1.xs('b_1', level=1, axis=1) # 按行从大到小排名,method可选:dense(不跳号)/min(相同值取最小排名)/max(相同值取最大排名) rank_results = b1_cols.rank(axis=1, ascending=False, method='dense') # 将排名结果转为多级列,一级列统一命名为Rank,二级列对应原一级列 rank_cols = pd.MultiIndex.from_tuples([('Rank', col) for col in rank_results.columns]) rank_results.columns = rank_cols # 合并到原DataFrame df1 = pd.concat([df1, rank_results], axis=1) # 查看结果 print(df1)
动态扩展说明
- 新增一级列:比如后续添加
D1列组(包含a_1、b_1、c_1),xs('b_1', level=1, axis=1)会自动包含D1下的b_1列,排名代码无需修改。 - 新增行:直接在原DataFrame追加行后,重新运行排名代码即可,
rank方法会自动计算新行的排名。
为什么不推荐拆分合并?
拆分后再合并需要额外处理列名匹配、索引对齐,代码冗余且容易出错,尤其是当列结构变化时,还要调整合并逻辑,维护成本远高于直接添加排名列的方案。
内容的提问来源于stack exchange,提问作者scstx
相关产品推荐
相关产品推荐

