解压字典数据以创建多索引熊猫数据框

问题描述 投票:0回答:1

我有一个包含嵌套字典的数据集,我想将其解包并形成多索引数据框。

数据框应包含“年份”列,以及每年“结果类型”的子列(在本例中为产量和质量)。

典型数据集:

datalist= [
    {
        'trial': 'efr1',
        'location': 'aberdeen',
        '2010': {'yield': '100', 'quality': '97'},
        '2011': {'yield': '90', 'quality': '87'},
        '2012': {'yield': '88', 'quality': '90'}
    
    },
    {
        'trial': 'efr2',
        'location': 'bristol',
        '2010': {'yield': '88', 'quality': '90'},
        '2011': {'yield': '75', 'quality': '82'},
        '2012': {'yield': '77', 'quality': '80'}
    
    },
    {
        'trial': 'axy1',
        'location': 'newcastle',
        '2010': {'yield': '91', 'quality': '95'},
        '2011': {'yield': '93', 'quality': '93'},
        '2012': {'yield': '75', 'quality': '97'}
    }   
]

使用 Dataframe.from_dict() 生成一个带有嵌入字典元素的表,我不知道如何解压并拆分为子列。

另一方面,使用 json_normalize() 会生成一个带有复合标题的平面表格,我不知道如何将其转换为具有我需要的结构的多索引框架...

Results with Dataframe.from_dict() and json_normalize()

pandas dataframe dictionary multi-index
1个回答
0
投票

如果我理解正确,您可以使用

pandas.json_normalize
,然后将
year.type
列转换为 MultiIndex (使用
str.split
):

out = (
 pd.json_normalize(datalist)
   .set_index(['trial', 'location'])
   .pipe(lambda d: d.set_axis(d.columns.str.split('.', expand=True), axis=1))
)

变体:

out =  pd.json_normalize(datalist).set_index(['trial', 'location'])
out.columns = out.columns.str.split('.', expand=True)

输出:

                 2010          2011          2012        
                yield quality yield quality yield quality
trial location                                           
efr1  aberdeen    100      97    90      87    88      90
efr2  bristol      88      90    75      82    77      80
axy1  newcastle    91      95    93      93    75      97

pd.json_normalize(datalist)
之后的中间:

  trial   location 2010.yield 2010.quality 2011.yield 2011.quality 2012.yield 2012.quality
0  efr1   aberdeen        100           97         90           87         88           90
1  efr2    bristol         88           90         75           82         77           80
2  axy1  newcastle         91           95         93           93         75           97
© www.soinside.com 2019 - 2024. All rights reserved.