如何用Lambda函数对带元组索引的Pandas数据框指定行按Num值排序?
解决方案
要实现仅对包含第三个元组元素的行按Num降序排序,同时保留原有分组结构(父项在前、同组子项跟随),需要结合索引的结构特征与Num列的值设计排序key,具体实现如下:
代码实现
# 生成索引与Num值的配对并排序 sorted_pairs = sorted(zip(dataTable.index, dataTable['Num']), key=lambda x: ( # 非元组索引(如Total)排在最后 not isinstance(x[0], tuple), # 按元组前两位分组,确保同组父项、子项归为一类 x[0][:2] if len(x[0]) == 3 else x[0], # 长度为3的元组按Num降序,其余按索引本身排序 -x[1] if len(x[0]) == 3 else x[0] )) # 提取排序后的索引并重新索引DataFrame dataTable = dataTable.reindex([idx for idx, num in sorted_pairs])
排序逻辑解释
第一排序条件:
not isinstance(x[0], tuple)
将非元组类型的索引(示例中的Total)优先级设为更高(布尔值True对应数值1,False对应0),确保这类行排在最后。第二排序条件:
x[0][:2] if len(x[0]) == 3 else x[0]- 对于长度为3的元组(如
('Total','A','Tuple')),取前两个元素作为分组标识,保证同组子项紧跟在父项(如('Total','A'))之后; - 对于长度为2的元组(父项),直接使用元组本身,确保父项在同组子项之前。
- 对于长度为3的元组(如
第三排序条件:
-x[1] if len(x[0]) == 3 else x[0]- 针对长度为3的元组,用
-x[1](Num值的负数)实现降序排序; - 其他情况(父项、非元组索引)保持原有字母顺序排序。
- 针对长度为3的元组,用
验证结果
执行上述代码后,DataFrame会输出你期望的结构:
Index Num ('Total', 'A') 23 ('Total', 'A', 'Tuple') 13 ('Total', 'A', 'Row') 7 ('Total', 'A', 'Pandas') 3 ('Total', 'B') 35 ('Total', 'B', 'Two') 23 ('Total', 'B', 'Rows') 12 ('Total', 'C') 54 ('Total', 'C', 'Row') 54 Total 112
内容的提问来源于stack exchange,提问作者Luke Hamilton
相关产品推荐
相关产品推荐

