如何将具有 MultiIndex 索引和具有字符串值的列的数据框转换为数据透视表 table?

How to convert a dataframe with MultiIndex indices and columns that has string values to a pivot table?

我有一个 pandas 数据框 df1 如下所示:

module  wind_on_share   wind_off_share  wind_total_share
variable    Wind-onshore power generation   Wind-offshore power generation  Wind power generation
model   scenario            
AIM/CGE 2.0 ADVANCE_2030_Price1.5C  high    NaN medium
SSP1-19 NaN NaN high
GCAM 4.2    SSP1-19 NaN NaN medium
IMAGE 3.0.1 SSP1-19 NaN NaN low
SSP1-26 NaN NaN low

数据框有包含 modelscenario 的 MultiIndex 索引。同样,它有包含 modulevariable 的 MultiIndex 列,如下所示:

[(   'wind_on_share',  'Wind-onshore power generation'),
            (  'wind_off_share', 'Wind-offshore power generation'),
            ('wind_total_share',          'Wind power generation')]

我想将此数据框转换为数据透视表 table,以便将现有列中的 modulevariable 添加到索引中。并且值应显示在单个列中,如 values。它应该看起来像下面 Excel 的屏幕截图:

我用 df1.pivot_table(index = "", values = "") 尝试了不同的方法,但到目前为止还没有成功。而且我不确定应该将哪些参数传递给索引和值。我也尝试了 df1.unstack()df1.reset_index(),但我不确定要传递哪些参数,因为到目前为止还没有成功。在这种情况下,创建枢轴 table 的合适方法是什么?

数据框看起来像下面的字典格式。

{('wind_on_share',
  'Wind-onshore power generation'): {('AIM/CGE 2.0',
   'ADVANCE_2030_Price1.5C'): 'high', ('AIM/CGE 2.0',
   'SSP1-19'): nan, ('GCAM 4.2', 'SSP1-19'): nan, ('IMAGE 3.0.1',
   'SSP1-19'): nan, ('IMAGE 3.0.1', 'SSP1-26'): nan, ('MESSAGE-GLOBIOM 1.0',
   'ADVANCE_2030_Price1.5C'): 'low', ('MESSAGE-GLOBIOM 1.0',
   'SSP1-19'): nan, },
 ('wind_off_share',
  'Wind-offshore power generation'): {('AIM/CGE 2.0',
   'ADVANCE_2030_Price1.5C'): nan, ('AIM/CGE 2.0',
   'SSP1-19'): nan, ('GCAM 4.2', 'SSP1-19'): nan, ('IMAGE 3.0.1',
   'SSP1-19'): nan, ('IMAGE 3.0.1', 'SSP1-26'): nan, ('MESSAGE-GLOBIOM 1.0',
   'ADVANCE_2030_Price1.5C'): 'low', ('MESSAGE-GLOBIOM 1.0',
   'SSP1-19'): nan},
 ('wind_total_share',
  'Wind power generation'): {('AIM/CGE 2.0',
   'ADVANCE_2030_Price1.5C'): 'medium', ('AIM/CGE 2.0',
   'SSP1-19'): 'high', ('GCAM 4.2', 'SSP1-19'): 'medium', ('IMAGE 3.0.1',
   'SSP1-19'): 'low', ('IMAGE 3.0.1',
   'SSP1-26'): 'low', ('MESSAGE-GLOBIOM 1.0', 'ADVANCE_2030_Price1.5C'): 'medium', ('MESSAGE-GLOBIOM 1.0',
   'SSP1-19'): 'low'}}

您可以从列中删除级别 -1(因为您不希望它出现在生成的数据框中),然后将数据框与 dropna=False 堆叠以保留 NaN 的值索引,然后最后调用 to_frame 将列名作为 value 传递,以将堆叠序列转换为数据帧。

>>> df.droplevel(-1,1).stack(dropna=False).to_frame('value')

输出:

                                                              value
AIM/CGE 2.0         ADVANCE_2030_Price1.5C wind_on_share       high
                                           wind_off_share       NaN
                                           wind_total_share  medium
                    SSP1-19                wind_on_share        NaN
                                           wind_off_share       NaN
                                           wind_total_share    high
GCAM 4.2            SSP1-19                wind_on_share        NaN
                                           wind_off_share       NaN
                                           wind_total_share  medium
IMAGE 3.0.1         SSP1-19                wind_on_share        NaN
                                           wind_off_share       NaN
                                           wind_total_share     low
                    SSP1-26                wind_on_share        NaN
                                           wind_off_share       NaN
                                           wind_total_share     low
MESSAGE-GLOBIOM 1.0 ADVANCE_2030_Price1.5C wind_on_share        low
                                           wind_off_share       low
                                           wind_total_share  medium
                    SSP1-19                wind_on_share        NaN
                                           wind_off_share       NaN
                                           wind_total_share     low