如何在Pandas多重索引DataFrame中按自定义偏好排序索引
问题:调整Pandas多重索引中Scenario_Model的顺序并绘图
我有一个Pandas DataFrame df,它包含Gx.Region和Scenario_Model的多重索引。Scenario_Model索引默认按字母顺序排列为des、pes、tes,绘图时也遵循该顺序。我希望将其重新排序为pes、tes、des并据此绘图,请问在Python Pandas中能否实现?
示例代码:
import pandas as pd dict_data = {('Value', 2023, 'BatteryStorage'): {('Central Africa', 'des'): 0.0, ('Central Africa', 'pes'): 0.0, ('Central Africa', 'tes'): 0.0, ('Eastern Africa', 'des'): 0.0, ('Eastern Africa', 'pes'): 0.0, ('Eastern Africa', 'tes'): 0.0, ('North Africa', 'des'): 0.0, ('North Africa', 'pes'): 0.0, ('North Africa', 'tes'): 0.0, ('Southern Africa', 'des'): 504.0, ('Southern Africa', 'pes'): 100.0, ('Southern Africa', 'tes'): 360.0, ('West Africa', 'des'): 0.0, ('West Africa', 'pes'): 0.0, ('West Africa', 'tes'): 0.0}, ('Value', 2023, 'Biomass PP'): {('Central Africa', 'des'): 0.0, ('Central Africa', 'pes'): 0.0, ('Central Africa', 'tes'): 0.0, ('Eastern Africa', 'des'): 40, ('Eastern Africa', 'pes'): 10, ('Eastern Africa', 'tes'): 50, ('North Africa', 'des'): 0.0, ('North Africa', 'pes'): 0.0, ('North Africa', 'tes'): 0.0, ('Southern Africa', 'des'): 90.0, ('Southern Africa', 'pes'): 43.0, ('Southern Africa', 'tes'): 50.0, ('West Africa', 'des'): 200.0, ('West Africa', 'pes'): 150.0, ('West Africa', 'tes'): 100}} df_sample = pd.DataFrame.from_dict(dict_data) df_sample.plot(kind = "bar", stacked = True)
原始绘图效果:
解决方案
当然可以实现,以下是两种简洁的方法来调整Scenario_Model的索引顺序并绘图:
方法一:通过分类类型(Categorical)指定自定义顺序
将Scenario_Model层级转换为分类类型,明确指定你想要的顺序,再排序索引:
import pandas as pd # 定义目标顺序 target_order = ['pes', 'tes', 'des'] # 修改索引层级的类型为分类,指定顺序 df_sample.index = df_sample.index.set_levels( pd.Categorical(df_sample.index.levels[1], categories=target_order, ordered=True), level=1 # Scenario_Model是多重索引的第2层(索引从0开始) ) # 按索引排序 df_sorted = df_sample.sort_index(level=1) # 绘制调整顺序后的堆叠柱状图 df_sorted.plot(kind="bar", stacked=True)
方法二:使用sort_index的key参数映射排序
通过字典映射目标顺序的位置,让Pandas按照自定义规则排序:
import pandas as pd # 定义目标顺序及映射关系 target_order = ['pes', 'tes', 'des'] order_map = {v: i for i, v in enumerate(target_order)} # 按Scenario_Model层级排序,用key参数指定映射规则 df_sorted = df_sample.sort_index( level=1, key=lambda x: x.map(order_map) ) # 绘图 df_sorted.plot(kind="bar", stacked=True)
效果说明
两种方法都会让Scenario_Model按照pes→tes→des的顺序排列,绘图时的分组顺序也会同步更新,替代默认的字母排序。
内容的提问来源于stack exchange,提问作者hbstha123
相关产品推荐
相关产品推荐

