Pandas JSON(深入浅出)

Pandas JSON:轻松处理结构化数据的利器

在数据分析的世界里,JSON 格式就像是一本结构清晰的电子账本。它以键值对的形式组织数据,便于程序读取和传输。而 Pandas 作为 Python 中最强大的数据处理库,天生就擅长处理这类结构化信息。当你需要从 API 接口、配置文件或日志中提取数据时,Pandas JSON 就成了你手中最得力的工具。

Pandas 提供了 read_json()to_json() 两个核心方法,分别用于读取和写入 JSON 数据。它们不仅支持标准的 JSON 格式,还能智能处理嵌套结构、数组和多层级索引。掌握它们,你就等于掌握了从“原始数据”到“可分析表格”的转换能力。


从 JSON 字符串到 DataFrame:快速入门

想象一下,你从某个天气 API 获取了一段 JSON 数据,内容如下:

{
  "city": "北京",
  "date": "2024-04-05",
  "forecast": [
    {"day": "星期五", "high": 22, "low": 12},
    {"day": "星期六", "high": 25, "low": 14},
    {"day": "星期日", "high": 20, "low": 10}
  ]
}

这段数据虽然结构清晰,但直接使用原始格式分析起来非常麻烦。这时,Pandas JSON 就派上用场了。

import pandas as pd

json_str = '''
{
  "city": "北京",
  "date": "2024-04-05",
  "forecast": [
    {"day": "星期五", "high": 22, "low": 12},
    {"day": "星期六", "high": 25, "low": 14},
    {"day": "星期日", "high": 20, "low": 10}
  ]
}
'''

df = pd.read_json(json_str)

print(df)

代码注释:

  • json_str:定义一个包含 JSON 数据的字符串变量。
  • pd.read_json():Pandas 提供的读取 JSON 的核心函数,能自动识别结构并转换为 DataFrame。
  • 执行后,df 会是一个 DataFrame,其中 forecast 列的内容是列表,而其他列是普通值。

运行结果:

     city        date                                               forecast
0  北京  2024-04-05  [{'day': '星期五', 'high': 22, 'low': 12}, ...

可以看到,forecast 列没有被展开,而是保留为列表。这是因为 Pandas 默认不会自动展开嵌套结构。接下来我们学习如何处理这种嵌套。


展开嵌套数据:使用 json_normalize

真正的挑战来了——当 JSON 中包含列表或字典嵌套时,如何将它们“摊平”成标准表格?这时 json_normalize() 就是你的救星。

df_normalized = pd.json_normalize(
    data=json_str,
    record_path=['forecast'],      # 指定要展开的列表路径
    meta=['city', 'date'],         # 保留的元信息字段
    meta_prefix='info_'            # 元信息字段前缀,避免命名冲突
)

print(df_normalized)

代码注释:

  • record_path=['forecast']:告诉 Pandas 要展开 forecast 这个列表中的每一项。
  • meta=['city', 'date']:将 citydate 作为每行记录的上下文信息保留。
  • meta_prefix='info_':为元信息字段添加前缀,避免与嵌套字段名重复。

运行结果:

    day  high  low info_city   info_date
0  星期五    22   12     北京  2024-04-05
1  星期六    25   14     北京  2024-04-05
2  星期日    20   10     北京  2024-04-05

现在你得到了一个真正可用的 DataFrame,每一行代表一天的天气数据,字段清晰,可直接用于分析、绘图或导出。


处理复杂嵌套结构:多层嵌套的应对策略

现实中的 JSON 数据往往更复杂。比如,某个用户的评论数据可能包含多个层级:

[
  {
    "user": "张三",
    "post_id": 101,
    "comments": [
      {
        "text": "好文章!",
        "likes": 5,
        "author": {"name": "李四", "level": "高级"}
      },
      {
        "text": "有帮助",
        "likes": 3,
        "author": {"name": "王五", "level": "中级"}
      }
    ]
  }
]

这种情况下,json_normalizerecord_path 支持多级路径,用点号 . 分隔层级。

complex_json = '''
[
  {
    "user": "张三",
    "post_id": 101,
    "comments": [
      {
        "text": "好文章!",
        "likes": 5,
        "author": {"name": "李四", "level": "高级"}
      },
      {
        "text": "有帮助",
        "likes": 3,
        "author": {"name": "王五", "level": "中级"}
      }
    ]
  }
]
'''

df_complex = pd.json_normalize(
    data=complex_json,
    record_path=['comments'],          # 展开 comments 列表
    meta=['user', 'post_id'],          # 保留用户和帖子信息
    meta_prefix='post_',               # 前缀避免冲突
    record_prefix='comment_',          # 评论字段前缀
    errors='ignore'                    # 忽略无法展开的字段
)

print(df_complex)

代码注释:

  • record_path=['comments']:指定要展开的列表。
  • meta=['user', 'post_id']:保留原始上下文。
  • record_prefix='comment_':为展开字段加前缀,如 comment_text
  • errors='ignore':当遇到无法解析的字段时,跳过而非报错,提高健壮性。

输出结果:

   comment_text  comment_likes comment_author.name comment_author.level post_user  post_post_id
0    好文章!             5             李四               高级        张三          101
1    有帮助             3             王五               中级        张三          101

此时,所有嵌套信息都已“摊平”,可以轻松进行分组统计、筛选或导出。


从 DataFrame 写回 JSON:数据持久化

处理完数据后,你可能需要将结果保存为 JSON 文件,供其他系统使用。Pandas 提供了 to_json() 方法,支持多种输出格式。

df_complex.to_json('output_comments.json', orient='records', indent=2)

print("数据已成功保存至 output_comments.json")

代码注释:

  • to_json():将 DataFrame 转换为 JSON 格式并写入文件。
  • orient='records':输出格式为 JSON 数组,每行一个对象,适合大多数 API 场景。
  • indent=2:缩进两个空格,使文件更易读。
  • 文件路径:output_comments.json,可被前端、后端或其他程序读取。

生成的文件内容如下:

[
  {
    "comment_text": "好文章!",
    "comment_likes": 5,
    "comment_author.name": "李四",
    "comment_author.level": "高级",
    "post_user": "张三",
    "post_post_id": 101
  },
  {
    "comment_text": "有帮助",
    "comment_likes": 3,
    "comment_author.name": "王五",
    "comment_author.level": "中级",
    "post_user": "张三",
    "post_post_id": 101
  }
]

这种格式非常适合用于前后端数据交互、配置导出或日志记录。


Pandas JSON 的实用技巧与常见问题

常见问题 1:字段名冲突怎么办?

当你使用 json_normalize 时,如果嵌套字段和元信息字段同名,就会发生冲突。解决方法是使用 meta_prefixrecord_prefix 添加前缀。

常见问题 2:JSON 有空值或缺失字段?

Pandas 会自动将缺失值填充为 NaN,无需额外处理。你可以在后续使用 fillna() 进行补全。

实用技巧:批量处理多个 JSON 文件

如果你有多个 JSON 文件需要合并,可以用 pd.read_json() 逐个读取并用 pd.concat() 合并:

import glob

json_files = glob.glob("data/*.json")
dfs = [pd.read_json(file) for file in json_files]

combined_df = pd.concat(dfs, ignore_index=True)

print(f"共合并 {len(combined_df)} 条记录")

总结:Pandas JSON 是数据处理的“万能钥匙”

无论是从 API 获取数据、解析配置文件,还是将分析结果导出为标准格式,Pandas JSON 都能帮你高效完成任务。它不仅功能强大,而且使用简单,是每个数据处理工作者的必备技能。

掌握 read_jsonjson_normalizeto_json 三个核心方法,你就能轻松应对绝大多数 JSON 数据处理场景。下次当你面对一串复杂的 JSON 数据时,别再手动解析了——让 Pandas 来帮你“摊平”它。