You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python将含多层数组的JSON转为扁平化非规范化结构?

问题:将嵌套家族JSON扁平化为成员独立实体

原始输入JSON结构:

{
  "listOfHouses": [
    {
      "name": "House Lannister",
      "listOfMembers": [
        {
          "firstName": "Tywin",
          "lastName": "Lannister"
        },
        {
          "firstName": "Cersei",
          "lastName": "Lannister"
        }
      ]
    },
    {
      "name": "House Targaryen",
      "listOfMembers": [
        {
          "firstName": "Daenerys",
          "lastName": "Targaryen"
        }
      ]
    }
  ]
}

期望输出结构:

[
  {
    "name": "House Lannister",
    "firstName": "Tywin",
    "lastName": "Lannister"
  }, {
    "name": "House Lannister",
    "firstName": "Cersei",
    "lastName": "Lannister"
  }, {
    "name": "House Targaryen",
    "firstName": "Daenerys",
    "lastName": "Targaryen"
  }
]

用户尝试pd.json_normalize和递归遍历后未得到预期结果:

  • pd.json_normalize仅提取了家族层级数据,成员数组未展开
  • 递归遍历将所有字段打平为单字典,无法生成成员独立的实体结构

解决方案

方法1:使用pandas正确展开嵌套数组

pd.json_normalize支持通过record_path指定要展开的嵌套数组,meta参数保留父级字段,完美匹配需求:

import pandas as pd
import json

if __name__ == '__main__':
    with open('got-houses.json') as json_file:
        data = json.load(json_file)
        # 展开listOfMembers数组,同时保留家族name字段
        normalized_data = pd.json_normalize(
            data['listOfHouses'],
            record_path='listOfMembers',
            meta=['name']
        )
        # 转换为期望的字典列表格式
        result = normalized_data.to_dict('records')
        print(json.dumps(result, indent=2))

输出结果:

[
  {
    "firstName": "Tywin",
    "lastName": "Lannister",
    "name": "House Lannister"
  },
  {
    "firstName": "Cersei",
    "lastName": "Lannister",
    "name": "House Lannister"
  },
  {
    "firstName": "Daenerys",
    "lastName": "Targaryen",
    "name": "House Targaryen"
  }
]

方法2:纯Python通用递归展开方案

如果不依赖pandas,可实现通用递归函数,自动遍历嵌套结构并生成独立实体:

import json

def flatten_nested(data):
    result = []
    if isinstance(data, list):
        for item in data:
            result.extend(flatten_nested(item))
    elif isinstance(data, dict):
        # 查找当前字典中的嵌套数组字段
        nested_array_key = next((k for k, v in data.items() if isinstance(v, list)), None)
        if nested_array_key:
            # 提取父级非数组字段
            parent_fields = {k: v for k, v in data.items() if k != nested_array_key}
            # 遍历数组元素,合并父级字段后加入结果
            for member in data[nested_array_key]:
                merged_item = {**parent_fields, **member}
                result.extend(flatten_nested(merged_item))
        else:
            result.append(data)
    return result

if __name__ == '__main__':
    with open('got-houses.json') as json_file:
        data = json.load(json_file)
        result = flatten_nested(data['listOfHouses'])
        print(json.dumps(result, indent=2))

该函数可处理多层嵌套的通用结构,只要存在数组字段就会自动展开,并保留所有父级非数组字段。


内容的提问来源于stack exchange,提问作者Wolfgang Klenk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 22:50:43