57_Pandas中的json_normalize将字典列表转换为DataFrame

文章介绍了如何使用pandas的json_normalize函数将字典列表和嵌套字典转换为DataFrame,包括基本用法、record_path和meta参数的使用,以及如何处理复杂的JSON结构。此外,还提到了pandas.read_json作为替代方法和版本兼容性问题。
摘要由CSDN通过智能技术生成

57_Pandas中的json_normalize将字典列表转换为DataFrame

可以使用 pandas.json_normalize() 将具有公共键的字典列表转换为 pandas.DataFrame。

由于它是一种常用的JSON格式,可以通过Web API获取,所以能够将其转换为pandas.DataFrame是非常方便的。

在此,对以下内容进行说明。

  • 使用 pandas.DataFrame() 进行转换
  • pandas.json_normalize() 的基本用法
  • 更复杂的情况:arguments record_path, meta

使用 pandas.read_json() 直接读取 JSON 字符串或文件作为 pandas.DataFrame 而不是由字典或列表组成的对象。

请注意,pandas.json_normalize() 是从 pandas 1.0.0 提供的,在以前的版本中是作为 pandas.io.json.json_normalize() 提供的。从 1.2.2 开始,pandas.io.json.json_normalize() 仍然可以使用,但已弃用,并且会出现警告(FutureWarning)。

使用 pandas.DataFrame() 进行转换

以下面的字典列表为例:

import pandas as pd

l_simple = [{'name': 'Alice', 'age': 25},
            {'name': 'Bob'}]

字典中的key键成为列标签(列名),key不存在时的元素成为缺失值NaN。

print(pd.DataFrame(l_simple))
#     name   age
# 0  Alice  25.0
# 1    Bob   NaN

与 pandas.json_normalize() 的结果相同。

print(pd.json_normalize(l_simple))
#     name   age
# 0  Alice  25.0
# 1    Bob   NaN

pandas.json_normalize() 的基本用法

以字典为字典值的嵌套字典列表为例。

l_nested = [{'name': 'Alice', 'age': 25, 'id': {'x': 2, 'y': 8}},
            {'name': 'Bob', 'id': {'x': 10, 'y': 4}}]

使用 pandas.DataFrame() 时,值字典被转换为元素。

print(pd.DataFrame(l_nested))
#     name   age                 id
# 0  Alice  25.0   {'x': 2, 'y': 8}
# 1    Bob   NaN  {'x': 10, 'y': 4}

使用 pandas.json_normalize() 还将嵌套字典转换为每个键的单独列。

print(pd.json_normalize(l_nested))
#     name   age  id.x  id.y
# 0  Alice  25.0     2     8
# 1    Bob   NaN    10     4

嵌套部分,.默认为列名。这个分隔符可以用参数 sep 改变。

print(pd.json_normalize(l_nested, sep='_'))
#     name   age  id_x  id_y
# 0  Alice  25.0     2     8
# 1    Bob   NaN    10     4

更复杂的情况:arguments record_path, meta

如果字典值是如下所示的字典列表。

l_complex = [{'label': 'X',
              'info' : {'n': 'nx', 'm': 'mx'},
              'data': [{'a': 1, 'b': 2},
                       {'a': 3, 'b': 4}]},
             {'label': 'Y',
              'info' : {'n': 'ny', 'm': 'my'},
              'data': [{'a': 10, 'b': 20},
                       {'a': 30, 'b': 40}]}]

默认情况下,字典列表成为一个元素。

print(pd.json_normalize(l_complex))
#   label                                      data info.n info.m
# 0     X      [{'a': 1, 'b': 2}, {'a': 3, 'b': 4}]     nx     mx
# 1     Y  [{'a': 10, 'b': 20}, {'a': 30, 'b': 40}]     ny     my

如果在参数 record_path 中指定一个键,则只会转换与该键对应的值。可以使用参数 record_prefix 将前缀添加到列名。

print(pd.json_normalize(l_complex, record_path='data'))
#     a   b
# 0   1   2
# 1   3   4
# 2  10  20
# 3  30  40

print(pd.json_normalize(l_complex, record_path='data', record_prefix='data_'))
#    data_a  data_b
# 0       1       2
# 1       3       4
# 2      10      20
# 3      30      40

如果要转换其他键值,请使用参数 meta 指定它。可以使用参数 meta_prefix 将前缀添加到列名。

print(pd.json_normalize(l_complex, record_path='data'))
#     a   b
# 0   1   2
# 1   3   4
# 2  10  20
# 3  30  40

print(pd.json_normalize(l_complex, record_path='data', record_prefix='data_'))
#    data_a  data_b
# 0       1       2
# 1       3       4
# 2      10      20
# 3      30      40

如果要转换其他键值,请使用参数 meta 指定它。可以使用参数 meta_prefix 将前缀添加到列名。

print(pd.json_normalize(l_complex, record_path='data',
                        meta='label'))
#     a   b label
# 0   1   2     X
# 1   3   4     X
# 2  10  20     Y
# 3  30  40     Y

print(pd.json_normalize(l_complex, record_path='data',
                        meta='label', meta_prefix='meta_'))
#     a   b meta_label
# 0   1   2          X
# 1   3   4          X
# 2  10  20          Y
# 3  30  40          Y

如果 meta 指定的键对值是一个字典,则可以在列表 [[, ], …] 中指定子键。默认情况下,列名是 .,但在这里你可以用参数 sep 更改分隔符。

print(pd.json_normalize(l_complex, record_path='data',
                        meta='info'))
#     a   b                    info
# 0   1   2  {'n': 'nx', 'm': 'mx'}
# 1   3   4  {'n': 'nx', 'm': 'mx'}
# 2  10  20  {'n': 'ny', 'm': 'my'}
# 3  30  40  {'n': 'ny', 'm': 'my'}

print(pd.json_normalize(l_complex, record_path='data',
                        meta=[['info', 'n'], ['info', 'm']]))
#     a   b info.n info.m
# 0   1   2     nx     mx
# 1   3   4     nx     mx
# 2  10  20     ny     my
# 3  30  40     ny     my

print(pd.json_normalize(l_complex, record_path='data',
                        meta=[['info', 'n'], ['info', 'm']],
                        sep='_'))
#     a   b info_n info_m
# 0   1   2     nx     mx
# 1   3   4     nx     mx
# 2  10  20     ny     my
# 3  30  40     ny     my

要将此示例中的所有元素转换为 pandas.DataFrame,请设置:

print(pd.json_normalize(l_complex, record_path='data',
                        meta=['label', ['info', 'n'], ['info', 'm']],
                        sep='_'))
#     a   b label info_n info_m
# 0   1   2     X     nx     mx
# 1   3   4     X     nx     mx
# 2  10  20     Y     ny     my
# 3  30  40     Y     ny     my

请注意,即使单独指定子键,它也必须是像 meta=[[, ]] 这样的列表列表。如果 meta=[, ] 则出错。

print(pd.json_normalize(l_complex, record_path='data',
                        meta=[['info', 'n']]))
#     a   b info.n
# 0   1   2     nx
# 1   3   4     nx
# 2  10  20     ny
# 3  30  40     ny

# print(pd.json_normalize(l_complex, record_path='data',
#                         meta=['info', 'n']))
# KeyError: "Try running with errors='ignore' as key 'n' is not always present"
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值