如何展平多个嵌套的 json 并转换为数据框?

Posted

技术标签:

【中文标题】如何展平多个嵌套的 json 并转换为数据框?【英文标题】:How to flatten multiple nested json and convert to dataframe? 【发布时间】:2021-09-19 10:40:39 【问题描述】:

我正在尝试将 JSON(来自 AirTable)转换为可用于进一步数据转换的数据帧。

在将 JSON 转换为 列中的一个值具有嵌套列表的数据框后,我遇到了问题。

这是在我没有意识到 "Package" 包含来自其原始 JSON 列表的嵌套列表的情况下展开后的示例数据框。


|                    | Name                 |Source                                     |
| -------------------| ---------------------|-------------------------------------------|
|rec2mxAycpaC93jfz   | Luis Downes          |[Canceled - Lv1]                           |
|recIQ0HfCmRhUclti   | Milana Whitehouse    |[Canceled - Lv1,2019 - Lv2,2020 - Lv1]     |
|recOFVz0eajFblTzL   | Fatma Mayo           |[Canceled - Lv1,2019 - Lv4,2020 - Lv2]     |

这是示例 JSON, 是具有嵌套列表的数据字段,我想将其展平。

['id': 'rec2mxAycpaC93jfz',
 'fields': 'Name': 'Luis Downes',
             'Package': ['Canceled - Lv1'],
 'createdTime': '2017-08-25T17:05:45.000Z',
'id': 'recIQ0HfCmRhUclti',
 'fields': 'Name': 'Milana Whitehouse',
             Package': ['Canceled - Lv1', '2019 - Lv2', '2020 - Lv1'],
 'createdTime': '2017-08-25T17:05:46.000Z',
'id': 'recOFVz0eajFblTzL',
 'fields': 'Name': 'Fatma Mayo',
            Package': ['Canceled - Lv1', '2019 - Lv4', '2020 - Lv2'],
 'createdTime': '2017-08-25T17:05:47.000Z']
]

关于如何扁平化整个 JSON 的任何想法?我尝试了几种我找到的解决方案,包括this one 但它只会将第一条记录展平为单行。

# flattening JSON objects of arbitrary structure

def flatten_json(y):
    out = 

    def flatten(x, name=''):
        if type(x) is dict:
            for a in x:
                flatten(x[a], name + a + '_')
        elif type(x) is list:
            i = 0
            for a in x:
                flatten(a, name + str(i) + '_')
                i += 1
        else:
            out[name[:-1]] = x

    flatten(y)
    return out

下面列出了我想要实现的最终结果(JSON 或数据帧)


|                    | Name                 |Package- Canceled - Lv1 |Package- 2019 - Lv2 |Package- 2020 - Lv1 |Package- 2019 - Lv4 |Package- 2020 - Lv2 |                                          |
| -------------------| ---------------------|------------------------|--------------------|--------------------|--------------------|--------------------|
|rec2mxAycpaC93jfz   | Luis Downes          |1                       |0                   |0                   |0                   |0                   |
|recIQ0HfCmRhUclti   | Milana Whitehouse    |1                       |1                   |1                   |0                   |0                   |
|recOFVz0eajFblTzL   | Fatma Mayo           |1                       |0                   |0                   |1                   |1                   |

在这里提前感谢您的帮助!

【问题讨论】:

【参考方案1】:

通过json_normalize()get_dummies()

d = ['id': 'rec2mxAycpaC93jfz',
 'fields': 'Name': 'Luis Downes',
             'Package': ['Canceled - Lv1'],
 'createdTime': '2017-08-25T17:05:45.000Z',
'id': 'recIQ0HfCmRhUclti',
 'fields': 'Name': 'Milana Whitehouse',
             'Package': ['Canceled - Lv1', '2019 - Lv2', '2020 - Lv1'],
 'createdTime': '2017-08-25T17:05:46.000Z',
'id': 'recOFVz0eajFblTzL',
 'fields': 'Name': 'Fatma Mayo',
            'Package': ['Canceled - Lv1', '2019 - Lv4', '2020 - Lv2'],
 'createdTime': '2017-08-25T17:05:47.000Z'
]
 
df = pd.json_normalize(d)
dm = pd.get_dummies(df['fields.Package'].apply(pd.Series).stack()).sum(level=0)
pd.concat([df[['id','fields.Name']],dm], axis=1) 

                  id        fields.Name  2019 - Lv2  2019 - Lv4  2020 - Lv1  \
0  rec2mxAycpaC93jfz        Luis Downes           0           0           0   
1  recIQ0HfCmRhUclti  Milana Whitehouse           1           0           1   
2  recOFVz0eajFblTzL         Fatma Mayo           0           1           0   

   2020 - Lv2  Canceled - Lv1  
0           0               1  
1           0               1  
2           1               1  

【讨论】:

以上是关于如何展平多个嵌套的 json 并转换为数据框?的主要内容,如果未能解决你的问题,请参考以下文章

展平嵌套数据框并重新转换为原始形式

展平任何嵌套的 json 字符串并使用 spark scala 转换为数据帧

如何在python中将展平表转换为嵌套(分层)json?

将多个嵌套 JSON 转换为 Pandas 数据框

如何将嵌套的json结构转换为数据框

如何展平多级/嵌套 JSON?