如何用Python将含嵌套对象数组的JSON转为扁平化Excel
嵌套JSON转扁平化Excel的Python实现
问题背景
需要将包含多层嵌套对象数组的JSON文件转换为指定结构的扁平化Excel表格,现有代码无法正确输出预期格式。以下是待处理的JSON结构、预期表格及问题代码:
待处理JSON结构
{ "Documents": [ { "metaData": { "form": "1", "userNm": "1" }, "report": { "date": "1" }, "lossInfo": [ { "policy": { "effdate": "11", "efftime": "11" }, "year": { "current": "11", "previous": "11" } }, { "policy": { "effdate": "12", "efftime": "12" }, "year": { "current": "12", "previous": "12" } } ] }, { "metaData": { "form": "2", "userNm": "2" }, "report": { "date": "2" }, "lossInfo": [ { "policy": { "effdate": "21", "efftime": "21" }, "year": { "current": "22", "previous": "22" } }, { "policy": { "effdate": "21", "efftime": "21" }, "year": { "current": "22", "previous": "22" } } ] } ] }
预期扁平化表格结构
| metaData.form | metaData.userNm | report.date | policy.effdate | policy.efftime | year.current | year.previous |
|---|---|---|---|---|---|---|
| 1 | 1 | 1 | 11 | 11 | 11 | 11 |
| 1 | 1 | 1 | 12 | 12 | 12 | 12 |
| 2 | 2 | 2 | 21 | 21 | 22 | 22 |
| 2 | 2 | 2 | 21 | 21 | 22 | 22 |
现有问题代码
import json import pandas as pd def read_json(filename): jsonData = {} try: with open(filename, "r", encoding="utf-8") as f: jsonData = json.loads(f.read()) except: raise Exception(f"Reading {filename} file encountered an error") return jsonData json_data = read_json(filename=".json") df = pd.json_normalize(json_data,meta=['Documents']).explode('Documents').reset_index(drop=True) df = df.join(pd.json_normalize(df.pop('Documents'))) df = df.join(pd.json_normalize(df.pop("lossInfo").apply(pd.Series).stack().reset_index(drop=True)))
正确实现方案
核心思路是利用pandas.json_normalize的record_path和meta参数,直接指定嵌套数组的展开路径与外层保留字段,一次性完成扁平化处理。
完整代码
import json import pandas as pd def read_json(filename): try: with open(filename, "r", encoding="utf-8") as f: return json.load(f) except Exception as e: raise Exception(f"读取{filename}文件出错: {str(e)}") # 读取JSON数据(替换为你的实际文件名) json_data = read_json(filename="your_data.json") # 扁平化处理 df = pd.json_normalize( json_data, record_path=['Documents', 'lossInfo'], # 指定需要展开的嵌套数组路径 meta=[ ['Documents', 'metaData', 'form'], ['Documents', 'metaData', 'userNm'], ['Documents', 'report', 'date'] ] # 指定需要保留的外层字段路径 ) # 重命名列名以匹配预期格式 df.columns = [ 'policy.effdate', 'policy.efftime', 'year.current', 'year.previous', 'metaData.form', 'metaData.userNm', 'report.date' ] # 调整列顺序,与预期表格一致 df = df[['metaData.form', 'metaData.userNm', 'report.date', 'policy.effdate', 'policy.efftime', 'year.current', 'year.previous']] # 导出为Excel(不含索引列) df.to_excel("flattened_result.xlsx", index=False)
代码说明
record_path=['Documents', 'lossInfo']:明确指定要展开的嵌套数组层级,将每个Documents下的lossInfo数组元素拆分为独立行;meta参数:提取外层需要保留的关联字段,通过多层列表精准定位字段路径;- 列名重命名与顺序调整:确保最终表格的列名、顺序完全匹配预期;
- 导出Excel时设置
index=False,避免生成多余的索引列。
内容的提问来源于stack exchange,提问作者AchillesCK
相关产品推荐
相关产品推荐

