56_Pandas读取 JSON 字符串/文件 (read_json)

56_Pandas读取 JSON 字符串/文件 (read_json)

使用pandas.read_json()函数,可以将JSON格式字符串(str类型)和文件读取为pandas.DataFrame。它还支持 JSON 行 (.jsonl)。

读取成pandas.DataFrame后,可以做各种数据分析,也可以用to_csv()方法保存成csv文件,这样就可以很方便的通过pandas将JSON文件转为CSV文件。

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

  • pandas.read_json() 的基本用法
    • 读取 JSON 格式字符串
    • 读取JSON格式文件
      • 读取压缩文件:参数compression
  • 指定格式:参数orient
  • 读取 JSON 行 (.jsonl)
  • 读取 JSON 字符串/文件的一部分

pandas.read_json() 的基本用法

用作示例的字符串和文件是在以下文章中创建的。

读取 JSON 格式字符串

如果将 JSON 格式的字符串传递给 pandas.read_json() 函数的第一个参数,该字符串将被转换为 pandas.DataFrame。

import pandas as pd
import json

s = '{"col1":{"row1":1,"row2":2,"row3":3},"col2":{"row1":"a","row2":"x","row3":"\u554a"}}'

df_s = pd.read_json(s)

print(df_s)
#       col1 col2
# row1     1    a
# row2     2    x
# row3     3    啊

将原始字符串中的 Unicode 转义序列 \uXXXX 转换为相应的字符。 注意JSON字符串中的引号必须是双引号”。单引号’会导致错误(ValueError)。

s_single_quote = "{'col1':{'row1':1,'row2':2,'row3':3},'col2':{'row1':'a','row2':'x','row3':'\u554a'}}"

# df_s_single_quote = pd.read_json(s_single_quote)
# ValueError: Expected object or value

对于使用单引号 ’ 的字符串,使用字符串方法 replace() 将单引号 ’ 替换为双引号 “。

print(pd.read_json(s_single_quote.replace("'", '"')))
#       col1 col2
# row1     1    a
# row2     2    x
# row3     3    啊

读取JSON格式文件

如果将 JSON 格式文件路径传递给 pandas.read_json() 函数的第一个参数,该文件将被读取为 pandas.DataFrame。

df_f = pd.read_json('data/sample_from_pandas_columns.json')

print(df_f)
#       col1 col2
# row1     1    a
# row2     2    x
# row3     3    啊

读取压缩文件:参数compression

pandas 0.21.0版本加入了参数compression,指定’gzip’, ‘bz2’, ‘zip’, ‘xz’可以直接读取压缩文件。

如果扩展名是.gz、.bz2、.zip、.xz,设置compression=’infer’会自动选择对应的压缩方式。

df_gzip = pd.read_json('data/sample_from_pandas_columns.gz', compression='infer')

print(df_gzip)
#       col1 col2
# row1     1    a
# row2     2    x
# row3     3    啊

请注意,这仅适用于压缩的单个文件,无法读取包含多个文件的 zip。

指定格式:参数orient

pandas.DataFrame的行标签index、column标签column、value值如何赋值JSON的内容有以下几种格式。

有关实际示例,请参阅下面的文章。

注意,如果要读取的字符串或文件的格式与orient参数中指定的格式不同,会导致行列互换或出错。

df_s_index = pd.read_json(s, orient='index')

print(df_s_index)
#      row1 row2 row3
# col1    1    2    3
# col2    a    x    啊

# df_s_split = pd.read_json(s, orient='split')
# ValueError: JSON data had unexpected key(s): col2, col1

读取 JSON 行 (.jsonl)

JSON 行 (.jsonl) 是用换行符分隔的 JSON。

如果参数 orient=‘records’ 和参数 lines=True,您可以使用 pandas.read_json() 读取 JSON 行 (.jsonl)。

s_jsonl = '''{"col1":1,"col2":"a"}
{"col1":2,"col2":"x"}
{"col1":3,"col2":"\u554a"}'''

print(s_jsonl)
# {"col1":1,"col2":"a"}
# {"col1":2,"col2":"x"}
# {"col1":3,"col2":"啊"}

df_s_jsonl = pd.read_json(s_jsonl, orient='records', lines=True)

print(df_s_jsonl)
#    col1 col2
# 0     1    a
# 1     2    x
# 2     3    啊

要读取 JSONL 文件,只需在第一个参数中指定文件路径,如上例所示。

读取 JSON 字符串/文件的一部分

事实上,可以通过Web API等获取的JSON除了作为pandas.DataFrame读取的数据之外还有其他信息,因此在很多情况下不能直接应用pandas.read_json()。

在这种情况下,可以按以下流程阅读。可能有更好的方法。
1.使用标准库json模块的json.loads()和json.load()将JSON字符串和文件作为
2.字典读取 从字典中提取你想读的部分
3.使用 json.dumps() 将提取的部分转换为字符串
4.将字符串传递给 pandas.read_json()

以下面的嵌套 JSON 字符串为例。

s_nested = '{"OTHER": "x", "DATA": {"col1":{"row1":1,"row2":2},"col2":{"row1":"a","row2":"x"}}}'

如果按原样传递给 pandas.read_json() ,它将如下所示。

print(pd.read_json(s_nested))
#                             DATA OTHER
# col1      {'row1': 1, 'row2': 2}     x
# col2  {'row1': 'a', 'row2': 'x'}     x

首先,使用 json.loads() 将其转换为字典。 json.load() 加载文件。

d = json.loads(s_nested)

print(d)
# {'OTHER': 'x', 'DATA': {'col1': {'row1': 1, 'row2': 2}, 'col2': {'row1': 'a', 'row2': 'x'}}}

print(type(d))
# <class 'dict'>

从字典中提取要读取的部分作为 pandas.DataFrame。如果嵌套很深,则重复 [key name] [key name]。

d_target = d['DATA']

print(d_target)
# {'col1': {'row1': 1, 'row2': 2}, 'col2': {'row1': 'a', 'row2': 'x'}}

print(type(d_target))
# <class 'dict'>

使用 json.dumps() 转换为字符串。

s_target = json.dumps(d_target)

print(s_target)
# {"col1": {"row1": 1, "row2": 2}, "col2": {"row1": "a", "row2": "x"}}

print(type(s_target))
# <class 'str'>

传递给 pandas.read_json()。根据格式指定参数方向。示例默认值(orient=‘columns’)。

df_target = pd.read_json(s_target)

print(df_target)
#       col1 col2
# row1     1    a
# row2     2    x

一起写也OK了。

df_target2 = pd.read_json(json.dumps(json.loads(s_nested)['DATA']))

print(df_target2)
#       col1 col2
# row1     1    a
# row2     2    x

如果你要阅读的部分是orient=‘records’(字典列表)格式,你可以使用pandas.io.json.json_normalize()将字典列表直接转换为pandas.DataFrame。

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2023年3月26日
下一篇 2023年3月26日

相关推荐