【问题标题】:How to convert a pandas dataframe to matrix format in Python?如何在 Python 中将 pandas 数据框转换为矩阵格式?
【发布时间】:2021-09-27 14:31:26
【问题描述】:

我有一个熊猫数据框df,如图所示。 (最后给出df.to_dict()):

model   scenario    module      
AIM/CGE 2.0 ADVANCE_2020_1.5C-2100  wind_total_share    high    high
SSP1-19 wind_total_share    high    high
SSP2-19 wind_total_share    high    high
AIM/CGE 2.1 CD-LINKS_NPi2020_400    wind_total_share    high    high
TERL_15D_LowCarbonTransportPolicy   wind_total_share    medium  medium
TERL_15D_NoTransportPolicy  wind_total_share    medium  medium
GCAM 4.2    SSP1-19 wind_total_share    medium  medium
IMAGE 3.0.1 IMA15-AGInt wind_total_share    low low
IMA15-Def   wind_total_share    low low
IMA15-Eff   wind_total_share    low low

modelscenariomodule 是索引,而 InfrastructureInvestment 是数据框的两列。我想将这两列转换为矩阵格式,其中基础设施类似于 x 轴,投资类似于 Y 轴。此外,无论是在基础设施方面还是在投资方面,我都需要将它们分为低、中、高。 在单元格中,我想要模型名称和满足给定变量(投资基础设施)的给定类别(低/中/高)的场景,如下面的屏幕截图所示。在某些情况下,基础设施的情景较高,而投资的情景较低或中等,反之亦然。

我还想要另一个矩阵,它显示落入给定单元格的场景数量。第二个矩阵矩阵应该如下所示:

我不熟悉通过修改现有的 pandas 数据框来获得这种矩阵格式。是否有任何可用的功能或模块可用于此目的?如何使用 Python 将我的数据框转换为屏幕截图中所示的矩阵格式?

df.to_dict() 如下所示:

{'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'}}

【问题讨论】:

  • 一个熊猫问题,包括可重复的输入数据...仅此一项就值得 +1 :-)

标签: python python-3.x pandas dataframe matrix


【解决方案1】:

pivot_table 可以在这里提供帮助。

第二个矩阵可以直接用:

df.assign(values=1).pivot_table(values='values', index='Infrastructure',
          columns='Investment', aggfunc=sum)

给出:

Investment      high  low  medium
Infrastructure                   
high             4.0  NaN     NaN
low              NaN  3.0     NaN
medium           NaN  NaN     3.0

对于第一个,您可以先重置索引以构建预期值:

temp = df.reset_index(2, drop=True).reset_index()
temp['value'] = temp['level_0'] + ' ' + temp['level_1']
df2 = temp.pivot_table(values = 'value', index='Infrastructure',
                       columns='Investment', aggfunc=list)

df2 中,多个标识符被分组在一个列表中。如果您希望每行一个,您可以分解数据框:

df2.explode('high').explode('medium').explode('low')

得到

Investment                                    high                      low                                         medium
Infrastructure                                                                                                            
high            AIM/CGE 2.0 ADVANCE_2020_1.5C-2100                      NaN                                            NaN
high                           AIM/CGE 2.0 SSP1-19                      NaN                                            NaN
high                           AIM/CGE 2.0 SSP2-19                      NaN                                            NaN
high              AIM/CGE 2.1 CD-LINKS_NPi2020_400                      NaN                                            NaN
low                                            NaN  IMAGE 3.0.1 IMA15-AGInt                                            NaN
low                                            NaN    IMAGE 3.0.1 IMA15-Def                                            NaN
low                                            NaN    IMAGE 3.0.1 IMA15-Eff                                            NaN
medium                                         NaN                      NaN  AIM/CGE 2.1 TERL_15D_LowCarbonTransportPolicy
medium                                         NaN                      NaN         AIM/CGE 2.1 TERL_15D_NoTransportPolicy
medium                                         NaN                      NaN                               GCAM 4.2 SSP1-19

【讨论】:

    【解决方案2】:

    我进行了一段时间的头脑风暴,然后自己想出了解决方案。很长,但看起来是这样的。

    首先,我列出了基础设施和投资的高、中、低情景:

    infra_high = (df[df["Infrastructure"]=="high"].index.get_level_values(0) + " " + df[df["Infrastructure"]=="high"].index.get_level_values(1)).to_list()
    infra_medium = (df[df["Infrastructure"]=="medium"].index.get_level_values(0) + " " + df[df["Infrastructure"]=="medium"].index.get_level_values(1)).to_list()
    infra_low = (df[df["Infrastructure"]=="low"].index.get_level_values(0) + " " + df[df["Infrastructure"]=="low"].index.get_level_values(1)).to_list()
    
    invest_high = (df[df["Investment"]=="high"].index.get_level_values(0) + " " + df[df["Investment"]=="high"].index.get_level_values(1)).to_list()
    invest_medium = (df[df["Investment"]=="medium"].index.get_level_values(0) + " " + df[df["Investment"]=="medium"].index.get_level_values(1)).to_list()
    invest_low = (df[df["Investment"]=="low"].index.get_level_values(0) + " " + df[df["Investment"]=="low"].index.get_level_values(1)).to_list()
    

    接下来,我做了高、高的场景的交集;基础设施和投资的高、中、高、低如下:

    i1 = list(set(infra_high).intersection(set(invest_high)))
    i2 = list(set(infra_high).intersection(set(invest_medium)))
    i3 = list(set(infra_high).intersection(set(invest_low)))
    
    i4 = list(set(infra_medium).intersection(set(invest_high)))
    i5 = list(set(infra_medium).intersection(set(invest_medium)))
    i6 = list(set(infra_medium).intersection(set(invest_low)))
    
    i7 = list(set(infra_low).intersection(set(invest_high)))
    i8 = list(set(infra_low).intersection(set(invest_medium)))
    i9 = list(set(infra_low).intersection(set(invest_low)))
    

    接下来,我使用 Excel 文件重新创建了我想要制作的矩阵:

    然后,我为数据框的每个单元格分配列表如下:

    landing_zone1.loc["High","High"] = i1
    landing_zone1.loc["High","Medium"] = i2
    landing_zone1.loc["High","Low"] = i3
    
    landing_zone1.loc["Medium","High"] = i4
    landing_zone1.loc["Medium","Medium"] = i5
    landing_zone1.loc["Medium","Low"] = i6
    
    landing_zone1.loc["Low","High"] = i7
    landing_zone1.loc["Low","Medium"] = i8
    landing_zone1.loc["Low","Low"] = i9
    

    我使用每个列表的len() 对场景数量矩阵做了同样的事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-22
      • 1970-01-01
      • 2019-10-15
      • 1970-01-01
      相关资源
      最近更新 更多