如何在Python中通过关联DataFrame替换pandas双层索引值
Pandas多层索引标签替换解决方案
问题场景
我有一个以Asset(对应索引层As)和Scenario(对应索引层Scen)为双层索引的Pandas DataFrame,原始数据如下:
As Scen V1 v2 v3 0 1 34 45 78 0 2 30 95 58 0 3 14 -5 68 1 1 54 44 -8 1 2 34 45 78 1 3 39 40 96 2 1 34 45 68 2 2 94 -5 78 2 3 64 55 78
同时有两个映射关系的DataFrame:
Asset映射表
Index AssetName AssetExp 0 Asset1 X 1 Asset2 Y 2 Asset3 Z
Scenario映射表
Index ScenarioName sensitivity 1 Scenario1 5 2 Scenario2 10 3 Scenario3 5
需求是将原DataFrame的双层索引数值替换为目标名称,得到如下结果:
As Scen V1 v2 v3 Asset0 Scenario1 34 45 78 Asset0 Scenario2 30 95 58 Asset0 Scenario3 14 -5 68 Asset1 Scenario1 54 44 -8 Asset1 Scenario2 34 45 78 Asset1 Scenario3 39 40 96 Asset2 Scenario1 34 45 68 Asset2 Scenario2 94 -5 78 Asset2 Scenario3 64 55 78
解决方案
步骤1:构造示例数据(已有数据可跳过)
先构造对应DataFrame用于演示:
import pandas as pd # 构造主数据框 main_data = { 'V1': [34, 30, 14, 54, 34, 39, 34, 94, 64], 'v2': [45, 95, -5, 44, 45, 40, 45, -5, 55], 'v3': [78, 58, 68, -8, 78, 96, 68, 78, 78] } main_index = pd.MultiIndex.from_tuples( [(0,1), (0,2), (0,3), (1,1), (1,2), (1,3), (2,1), (2,2), (2,3)], names=['As', 'Scen'] ) df_main = pd.DataFrame(main_data, index=main_index) # 构造Asset映射表 asset_data = { 'AssetName': ['Asset1', 'Asset2', 'Asset3'], 'AssetExp': ['X', 'Y', 'Z'] } df_asset = pd.DataFrame(asset_data, index=[0, 1, 2]) # 构造Scenario映射表 scen_data = { 'ScenarioName': ['Scenario1', 'Scenario2', 'Scenario3'], 'sensitivity': [5, 10, 5] } df_scen = pd.DataFrame(scen_data, index=[1, 2, 3])
步骤2:替换索引标签
根据目标需求,As索引替换为Asset+原数值,Scen索引替换为映射表中的ScenarioName:
# 生成新的As索引标签:Asset拼接原索引数值 new_as_labels = [f'Asset{idx}' for idx in df_main.index.get_level_values('As')] # 从Scenario映射表中匹配对应名称 new_scen_labels = df_scen.loc[df_main.index.get_level_values('Scen'), 'ScenarioName'].tolist() # 构造新的双层索引 new_index = pd.MultiIndex.from_tuples( list(zip(new_as_labels, new_scen_labels)), names=['As', 'Scen'] ) # 替换主数据框的索引 df_main.index = new_index
可选:使用Asset映射表的名称
如果目标中的As名称是笔误,实际需要使用df_asset中的AssetName,修改new_as_labels的生成逻辑即可:
# 从Asset映射表中获取对应名称 new_as_labels = df_asset.loc[df_main.index.get_level_values('As'), 'AssetName'].tolist()
执行上述代码后,df_main就会生成符合要求的目标DataFrame。
内容的提问来源于stack exchange,提问作者Eve Chanatasig
相关产品推荐
相关产品推荐

