如何在Python中将pandas DataFrame转换为指定矩阵格式?
实现方案
不需要额外安装第三方模块,直接用pandas自带的pivot_table和crosstab函数即可完成需求,操作步骤如下:
1. 预处理数据
你提供的DataFrame已经自带model、scenario、module三层索引,我们先拼接模型和场景名称为单个字段,方便后续聚合展示:
import pandas as pd # 你提供的df.to_dict()数据 data = { 'Infrastructure': { ('AIM/CGE 2.0', 'ADVANCE_2020_1.5C-2100', 'wind_total_share'): 'high', ('AIM/CGE 2.0', 'SSP1-19', 'wind_total_share'): 'high', ('AIM/CGE 2.0', 'SSP2-19', 'wind_total_share'): 'high', ('AIM/CGE 2.1', 'CD-LINKS_NPi2020_400', 'wind_total_share'): 'high', ('AIM/CGE 2.1', 'TERL_15D_LowCarbonTransportPolicy', 'wind_total_share'): 'medium', ('AIM/CGE 2.1', 'TERL_15D_NoTransportPolicy', 'wind_total_share'): 'medium', ('GCAM 4.2', 'SSP1-19', 'wind_total_share'): 'medium', ('IMAGE 3.0.1', 'IMA15-AGInt', 'wind_total_share'): 'low', ('IMAGE 3.0.1', 'IMA15-Def', 'wind_total_share'): 'low', ('IMAGE 3.0.1', 'IMA15-Eff', 'wind_total_share'): 'low' }, 'Investment': { ('AIM/CGE 2.0', 'ADVANCE_2020_1.5C-2100', 'wind_total_share'): 'high', ('AIM/CGE 2.0', 'SSP1-19', 'wind_total_share'): 'high', ('AIM/CGE 2.0', 'SSP2-19', 'wind_total_share'): 'high', ('AIM/CGE 2.1', 'CD-LINKS_NPi2020_400', 'wind_total_share'): 'high', ('AIM/CGE 2.1', 'TERL_15D_LowCarbonTransportPolicy', 'wind_total_share'): 'medium', ('AIM/CGE 2.1', 'TERL_15D_NoTransportPolicy', 'wind_total_share'): 'medium', ('GCAM 4.2', 'SSP1-19', 'wind_total_share'): 'medium', ('IMAGE 3.0.1', 'IMA15-AGInt', 'wind_total_share'): 'low', ('IMAGE 3.0.1', 'IMA15-Def', 'wind_total_share'): 'low', ('IMAGE 3.0.1', 'IMA15-Eff', 'wind_total_share'): 'low' } } # 构造DataFrame并给索引命名 df = pd.DataFrame(data) df.index.names = ['model', 'scenario', 'module'] # 拼接模型和场景名称为新字段 df['model_scenario'] = df.index.get_level_values('model') + ' - ' + df.index.get_level_values('scenario')
2. 生成模型场景名称填充矩阵
以Investment分类为y轴,Infrastructure分类为x轴,单元格内填充对应分类下的所有模型+场景名称:
# 指定分类顺序,保证x/y轴按low→medium→high排序 level_order = ['low', 'medium', 'high'] name_matrix = df.pivot_table( index='Investment', # y轴是Investment分类 columns='Infrastructure', # x轴是Infrastructure分类 values='model_scenario', # 填充值为拼接好的模型场景名称 aggfunc=lambda x: '\n'.join(x), # 多个值用换行分隔,需要逗号分隔改成', '.join(x)即可 fill_value='' # 空单元格填充空字符串 ).reindex(index=level_order, columns=level_order) # 校正轴的顺序
3. 生成场景数量计数矩阵
直接用crosstab即可快速统计每个分类交叉下的场景数量:
count_matrix = pd.crosstab( df['Investment'], df['Infrastructure'] ).reindex(index=level_order, columns=level_order)
结果说明
你提供的样例数据中,所有场景的Infrastructure和Investment分类等级完全一致,所以最终生成的两个矩阵都只有对角线上有值,其余单元格为空/0。如果后续有分类等级不同的场景,会自动填充到对应的交叉单元格中。
如果需要导出结果,直接调用to_excel方法即可:
name_matrix.to_excel('模型场景名称矩阵.xlsx') count_matrix.to_excel('场景数量计数矩阵.xlsx')
内容的提问来源于stack exchange,提问作者hbstha123
相关产品推荐
相关产品推荐

