Pandas如何读取JSON数据:全面指南与实用技巧
在数据分析领域,JSON(JavaScript Object Notation)因其轻量级、易读和灵活的特性,已成为数据交换的主流格式之一,而Pandas作为Python数据分析的核心库,提供了强大的JSON数据读取功能,能够将半结构化的JSON数据高效转化为结构化的DataFrame对象,便于后续的数据清洗、处理与分析,本文将详细介绍Pandas读取JSON数据的多种方法、核心参数、常见场景及实用技巧,帮助你轻松应对不同类型的JSON数据。
核心方法:pandas.read_json()
Pandas读取JSON数据的核心函数是read_json(),它位于pandas.io.json模块中(通常无需手动导入,直接通过pd.read_json()调用),该函数支持从文件路径、URL、字符串等多种来源读取JSON数据,并能自动解析常见的JSON结构(如数组、嵌套对象等)。
基本语法
import pandas as pd
# 从文件读取
df = pd.read_json('data.json')
# 从字符串读取
json_str = '[{"name": "Alice", "age": 25}, {"name": "Bob", "age": 30}]'
df = pd.read_json(json_str)
# 从URL读取
df = pd.read_json('https://example.com/data.json')
关键参数解析
read_json()提供了丰富的参数,用于控制数据的解析方式、列类型处理、日期解析等,以下是常用参数的详细说明:
orient:指定JSON数据的结构
JSON数据的结构多样,orient参数用于明确数据的布局,帮助Pandas正确解析,常见的取值包括:
-
records(默认):JSON数组,每个元素是一个字典(字典的键为列名)。
示例JSON:[{"col1": 1, "col2": "a"}, {"col1": 2, "col2": "b"}]
解析结果:直接生成DataFrame,列名为col1、col2。 -
index:以索引为键的JSON对象,每个键对应一个字典(字典的键为列名)。
示例JSON:{"row1": {"col1": 1, "col2": "a"}, "row2": {"col1": 2, "col2": "b"}}
解析结果:索引为row1、row2,列为col1、col2。 -
columns:以列名为键的JSON对象,每个键对应一个数组(数组元素为该列的值)。
示例JSON:{"col1": [1, 2], "col2": ["a", "b"]}
解析结果:列名为col1、col2,索引为默认数字索引。 -
values:仅包含值的JSON数组(无列名和索引)。
示例JSON:[[1, "a"], [2, "b"]]
解析结果:列名为默认数字列(0, 1),索引为默认数字索引。 -
split:分三部分存储的JSON对象(包含index、columns、data)。
示例JSON:{"index": ["row1", "row2"], "columns": ["col1", "col2"], "data": [[1, "a"], [2, "b"]]}
解析结果:完整还原DataFrame结构。 -
table:包含schema和data的JSON(类似Pandas的表格导出格式)。
示例JSON:{"schema": {"fields": [{"name": "col1", "type": "integer"}, {"name": "col2", "type": "string"}], "primaryKey": ["col1"]}, "data": [{"col1": 1, "col2": "a"}, {"col1": 2, "col2": "b"}]}
解析结果:按schema定义的列类型生成DataFrame。
lines:按行解析JSON(每行一个JSON对象)
当JSON数据以“换行分隔JSON”(NDJSON)格式存储时(即每行是一个独立的JSON对象,文件整体是一个JSON对象数组),需设置lines=True。
示例场景:日志文件logs.json内容如下:
{"timestamp": "2023-01-01 10:00", "event": "login", "user": "Alice"}
{"timestamp": "2023-01-01 10:01", "event": "logout", "user": "Bob"}
读取方式:
df = pd.read_json('logs.json', lines=True)
解析结果:生成包含timestamp、event、user三列的DataFrame。
convert_dates:自动解析日期列
JSON中的日期通常以字符串存储(如"2023-01-01"),通过convert_dates参数可指定需要转换为日期格式的列名。
示例:
json_data = '{"date": "2023-01-01", "value": 100}'
df = pd.read_json(json_data, convert_dates=['date'])
print(df.dtypes) # 输出:date datetime64[ns], value int64
若未指定,Pandas会尝试自动识别日期列(默认开启infer_datetime_format=True),但复杂日期格式建议手动指定。
dtype:指定列的数据类型
为避免Pandas自动推断类型导致精度问题(如将"001"推断为1),可通过dtype参数显式指定列类型。
示例:
json_data = '[{"id": "001", "score": 95.5}, {"id": "002", "score": 88.0}]'
df = pd.read_json(json_data, dtype={'id': str, 'score': float})
print(df.dtypes) # 输出:id object, score float64
encoding:指定文件编码
读取非UTF-8编码的JSON文件(如GBK、ISO-8859-1)时,需通过encoding参数指定编码格式。
示例:
df = pd.read_json('data_gbk.json', encoding='gbk')
chunksize:分块读取大文件
对于大型JSON文件(如数GB),直接读取可能导致内存不足,使用chunksize参数可分块读取,返回一个迭代器,逐块处理数据。
示例:
chunk_iter = pd.read_json('large_data.json', lines=True, chunksize=10000)
for chunk in chunk_iter:
# 逐块处理数据(如过滤、聚合)
processed_chunk = chunk[chunk['age'] > 18]
processed_chunk.to_csv('processed_data.csv', mode='a', header=False)
常见场景与解决方案
场景1:读取嵌套JSON数据
JSON数据常包含嵌套结构(如字典、列表),直接读取会导致嵌套列的类型为object(字典或列表),需结合json_normalize()函数展开嵌套数据。
示例:读取包含嵌套字典的JSON
json_data = '''
[
{"name": "Alice", "info": {"age": 25, "city": "Beijing"}},
{"name": "Bob", "info": {"age": 30, "city": "Shanghai"}}
]
'''
# 先读取为DataFrame
df = pd.read_json(json_data)
print(df) # 输出:name info(列类型为object)
# 展开嵌套的info列
from pandas import json_normalize
df_normalized = json_normalize(df['info'])
df_final = pd.concat([df['name'], df_normalized], axis=1)
print(df_final)
# 输出:
# name age city
# 0 Alice 25 Beijing
# 1 Bob 30 Shanghai
场景2:读取半结构化JSON(动态键)
当JSON的键不固定(如动态字段)时,可通过orient='columns'读取,并结合字典推导或正则表达式处理动态键。
示例:
json_data = '''
{
"user1": {"math": 90, "english": 85},
"user2": {"math": 88, "physics": 92}
}
'''
df = pd.read_json(json_data, orient='columns').T # 转置使user成为索引
print(df)
# 输出:
# math english physics
# user1 90 85.0 NaN
# user2 88 NaN 92.0
场景3:从API响应读取JSON
许多API返回JSON格式的数据,直接通过requests库获取响应后



还没有评论,来说两句吧...