看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
pandas 内置的 Json 数据转换方法 json_normalize(),它可以对以半结构 json 格式的数据进行解析,最终生成 DataFrame,进而对数据进行更多操作。 json_normalize() 方法非常强大,能够完成几乎所有复杂的解析 JSON 场景。
图示:
pandas 的 json_normalize() 是顶级方法,语法为:
pd.json_normalize(
data: 'dict | list[dict]',
record_path: 'str | list | None' = None,
meta: 'str | list[str | list[str]] | None' = None,
meta_prefix: 'str | None' = None,
record_prefix: 'str | None' = None,
errors: 'str' = 'raise',
sep: 'str' = '.',
max_level: 'int | None' = None
) -> 'DataFrame'
返回的是一个 DataFrame,是将半结构化JSON数据规范化为平面表。
简单理解下几个重点参数,参数中 data 可以接受一个字典或者列表,列表的话元素由字典组成,在保持这个外层规范下,内层可以有更加复杂的格式。record_path 是具体的数据记录,是我们记录的数据主体,meta 则是这个数据的说明描述,在内层结构中只有一条。
参数如下:
阅读数据是任何数据科学项目的第一步。作为一名机器学习实践者或数据科学家,您肯定会遇到JSON(JavaScript对象表示法)数据。JSON是一种广泛用于存储和交换数据的格式。例如,像MongoDB这样的NoSQL数据库以JSON格式存储数据,RESTAPI的响应大多以JSON格式提供。
json_normalize() 在记录网络传输数据,比如爬虫接口数据非常有用。
以下是一些简单示例。
首先看看列表内字典嵌套的情形,列表中一个元素是一条记录:
data = [
{"id": 1, "name": {"first": "Coleen", "last": "Volk"}},
{"name": {"given": "Mark", "family": "Regner"}},
{"id": 2, "name": "Faye Raker"},
]
# 没有指定 max_level,则处理所有层级数据
pd.json_normalize(data)
'''
id name.first name.last name.given name.family name
0 1.0 Coleen Volk NaN NaN NaN
1 NaN NaN NaN Mark Regner NaN
2 2.0 NaN NaN NaN NaN Faye Raker
'''
嵌套层级更多的:
data = [
{
"id": 1,
"name": "Cole Volk",
"fitness": {"height": 130, "weight": 60},
},
{"name": "Mark Reg", "fitness": {"height": 130, "weight": 60}},
{
"id": 2,
"name": "Faye Raker",
"fitness": {"height": 130, "weight": 60},
},
]
# 读取到到一层
pd.json_normalize(data, max_level=0)
'''
id name fitness
0 1.0 Cole Volk {'height': 130, 'weight': 60}
1 NaN Mark Reg {'height': 130, 'weight': 60}
2 2.0 Faye Raker {'height': 130, 'weight': 60}
'''
# 读取到第二层
pd.json_normalize(data, max_level=1)
'''
id name fitness.height fitness.weight
0 1.0 Cole Volk 130 60
1 NaN Mark Reg 130 60
2 2.0 Faye Raker 130 60
'''
以下是一个更加复杂的数据:
data = [
{
"state": "Florida",
"shortname": "FL",
"info": {"governor": "Rick Scott", "web": "gairuo.com"},
"counties": [
{"name": "Dade", "population": 12345},
{"name": "Broward", "population": 40000},
{"name": "Palm Beach", "population": 60000},
],
},
{
"state": "Ohio",
"shortname": "OH",
"info": {"governor": "John Kasich", "web": "sin80.com"},
"counties": [
{"name": "Summit", "population": 1234},
{"name": "Cuyahoga", "population": 1337},
],
},
]
# 记录都在 counties,元数据取 state、shortname 和
# info 中的 web, info 中的 governor 被舍弃
result = pd.json_normalize(
data,
record_path="counties",
meta=["state", "shortname", ["info", "web"]]
)
result
'''
name population state shortname info.web
0 Dade 12345 Florida FL gairuo.com
1 Broward 40000 Florida FL gairuo.com
2 Palm Beach 60000 Florida FL gairuo.com
3 Summit 1234 Ohio OH sin80.com
4 Cuyahoga 1337 Ohio OH sin80.com
'''
整体是一个字典结构:
data = {"A": [1, 2], "B": [3, 4]}
# 只取键为 B 的记录,列名加前缀
pd.json_normalize(data, record_path="B", record_prefix="Prefix.")
'''
Prefix.0
0 3
1 4
'''
以上我们是从 Python 对象(列表和字典)中读取数据,如果想要从其他方式读取数据可以用以下方法。
可以利用 Python 内置 json 库加载到字典:
# 本地文件
import json
# load data using Python JSON module
with open('data/simple.json','r') as f:
data = json.loads(f.read())
# Flattening JSON data
pd.json_normalize(data)
当然也可以使用 pd.read_json('data.json')
,详情见 pandas 文件或数据的读取和导出 中的介绍。
读取互联网上的数据,您需要使用 JSON 格式的 API 响应。最简单的方法是使用 Python request 模块:
import requests
URL = 'http://raw.githubusercontent.com/BindiChen/machine-learning/master/data-analysis/027-pandas-convert-json/data/simple.json'
# 读取数据,并转为 json 格式
data = requests.get(URL).json()
# Flattening JSON data
pd.json_normalize(data)
有时候提供的数据并不是最外层由列表和字典组成,而是直接由多个字典形式换行保存在文件里,形如:
# file.txt 内容
'''
{'a':{...}, 'b':{...}}
{'a':{...}, 'b':{...}}
'''
可用以下方法解决:
ser = pd.read_json('file.txt', lines=True, typ='series')
df = pd.json_normalize(ser)
所有列会有形如 a.xx、b.xx 的前缀。
更新时间:2023-03-01 10:33:57 标签:pandas json 数据