基于双自定义字典的DataFrame定制化排序问题:现有代码失效的排查与实现方案
解决自定义字典多列排序问题
你的问题出在sort_values的key参数用法上——x.map()只能接受一个字典,没办法同时传入两个自定义字典来分别处理category和segment列。另外,根据你描述的期望排序逻辑,我们需要调整排序的优先级:先按category的分组(比如HC/AMG HC为一组,S/AMG S为一组)排序,再按segment的优先级排序,最后在每个组内按category自身的顺序排序。
下面是具体的实现步骤:
1. 准备示例数据和自定义字典
import pandas as pd # 示例数据集 data = {'category': {0: 'HC', 1: 'AMG HC', 2: 'S', 3: 'AMG MUP', 4: 'MUP', 5: 'S', 6: 'AMG S', 7: 'HCA'}, 'segment': {0: 'Offline', 1: 'Offline', 2: 'Offline', 3: 'Offline', 4: 'Online', 5: 'Online', 6: 'Offline', 7: 'Independent'}, 'ytd2020': {0: '101142', 1: '38541', 2: '55653', 3: '19561', 4: '84921', 5: '99301', 6: '80212', 7: '95731'}, 'ytd2021': {0: '105726', 1: '39463', 2: '57537', 3: '21402', 4: '90310', 5: '97283', 6: '87011', 7: '119289'}, 'Evolution': {0: '4.5%', 1: '2.4%', 2: '2.1%', 3: '4.3%', 4: '8.2%', 5: '-2.0%', 6: '12.4%', 7: '24.6%'}} df4 = pd.DataFrame(data) # 自定义排序字典 custom_dict = {'HC': 0, 'AMG HC': 1, 'S': 2, 'AMG S': 3, 'HCA':4, 'AMG HCA':5, 'MUP':6, 'AMG MUP':7} custom_dict2 = {'Offline': 0, 'Online': 1, 'Independent':2}
2. 实现符合预期的排序
我们先通过临时列明确排序优先级:
category_group:把HC/AMG HC归为一组,S/AMG S归为一组,以此类推(用custom_dict的值整除2实现)segment_order:用custom_dict2映射得到segment的排序值category_order:用custom_dict映射得到category自身的排序值
然后按这三个列排序,最后删除临时列:
# 生成临时排序键列 df4['category_group'] = df4['category'].map(custom_dict) // 2 df4['segment_order'] = df4['segment'].map(custom_dict2) df4['category_order'] = df4['category'].map(custom_dict) # 按优先级排序 df4_sorted = df4.sort_values( by=['category_group', 'segment_order', 'category_order'] ).drop(columns=['category_group', 'segment_order', 'category_order'])
这样排序后的结果就会符合你的期望:先展示所有HC/AMG HC的条目(按Offline→Online→Independent顺序,每个segment下先HC后AMG HC),然后是S/AMG S的条目,以此类推。
3. 执行后续的数据重塑
把排序后的DataFrame代入你的重塑代码即可:
ytd1 = 'ytd2020' ytd2 = 'ytd2021' df4_reshaped = (df4_sorted.set_index(['category', 'segment'], append=True) .unstack() .swaplevel(axis=1) .sort_index(level=0, axis=1, ascending=False) .reindex([ytd1, ytd2, 'Evolution'], level=1, axis=1) .reset_index('category') )
为什么之前的代码无效?
你之前的key=lambda x: x.map(custom_dict, custom_dict2)写法是错误的——Series.map()只接受一个映射字典(或函数),无法同时处理两个列的不同字典。通过生成临时列的方式,我们可以清晰地定义多维度的排序优先级,避免这种语法错误。
内容的提问来源于stack exchange,提问作者nikita1221
相关产品推荐
相关产品推荐

