将嵌套JSON展平为pandas.DataFrame:基于字典值实现列的排序与命名
按固定嵌套对象类型展平JSON适配Pandas
我在参考Trenton McKinney的批量嵌套JSON展平方案时,遇到了JSON格式不一致的问题:嵌套的supplement数组里的元素类型固定但出现顺序不固定、可能缺失,导致展平后的DataFrame列顺序混乱,无法按supplementtype归类对应的price和rebate字段。
原方案的问题
原flatten_json函数会按数组索引生成列名(比如supplement_0_supplementtype),但因为supplement元素顺序不固定,不同JSON文件的同类型supplement会出现在不同列,无法统一格式:
原展平后DataFrame示例:
| product | product_id | supplement_0_supplementtype | supplement_0_price | supplement_1_supplementtype | supplement_1_price |
|---|---|---|---|---|---|
| example1 | id1 | RTZ | 300000 | CVB | 500000 |
| example2 | id2 | CVB | 500000 | RTZ | 300000 |
解决方案:按supplementtype重命名嵌套字段
通过手动遍历supplement数组,将每个元素的price和rebate字段重新命名为以supplementtype为标识的新键,再删除原supplement数组,最后生成DataFrame。这种方式能保证同类型supplement的字段对应固定列名,同时通过异常处理兼容字段缺失的情况。
单JSON处理示例代码
import pandas as pd d = { "product": "example_productname", "product_id": "example_productid", "product_type": "example_producttype", "producer": "example_producer", "currency": "example_currency", "client_id": "example_clientid", "supplement": [ { "supplementtype": "RTZ", "price": 300000, "rebate": "500" }, { "supplementtype": "CVB", "price": 500000, "rebate": "250" }, { "supplementtype": "JKL", "price": 100000, "rebate": "750" } ] } # 遍历supplement数组,重构字典字段 for s in d["supplement"]: try: d[f"supplement_{s['supplementtype']}_price"] = s["price"] except KeyError: pass try: d[f"supplement_{s['supplementtype']}_rebate"] = s["rebate"] except KeyError: pass # 删除原嵌套数组 del d["supplement"] # 生成DataFrame df = pd.DataFrame([d]) print(df)
执行后得到的DataFrame格式(列固定按supplementtype归类):
| product | product_id | product_type | producer | currency | client_id | supplement_RTZ_price | supplement_RTZ_rebate | supplement_CVB_price | supplement_CVB_rebate | supplement_JKL_price | supplement_JKL_rebate |
|---|---|---|---|---|---|---|---|---|---|---|---|
| example_productname | example_productid | example_producttype | example_producer | example_currency | example_clientid | 300000 | 500 | 500000 | 250 | 100000 | 750 |
批量处理JSON文件的代码
将上述逻辑整合到批量文件处理流程中:
import pandas as pd import json # 定义处理单个JSON字典的函数 def process_json(data: dict) -> dict: for s in data.get("supplement", []): # 处理price字段 try: data[f"supplement_{s['supplementtype']}_price"] = s["price"] except KeyError: pass # 处理rebate字段 try: data[f"supplement_{s['supplementtype']}_rebate"] = s["rebate"] except KeyError: pass # 删除原supplement字段(如果存在) data.pop("supplement", None) return data # 批量处理文件 files = ['test1.json', 'test2.json'] df_list = [] for file in files: with open(file, 'r') as f: data = json.loads(f.read()) processed_data = process_json(data) df_list.append(pd.DataFrame([processed_data])) # 合并所有DataFrame final_df = pd.concat(df_list).reset_index(drop=True) print(final_df)
关键说明
- 通过
f"supplement_{s['supplementtype']}_price"这种命名方式,直接将supplementtype作为列名的一部分,保证同类型字段对应固定列。 - 使用
try-except KeyError处理部分字段缺失的情况,避免程序报错。 - 批量处理时,Pandas会自动对齐所有列,缺失的字段会填充
NaN,保证最终DataFrame的列统一。
内容的提问来源于stack exchange,提问作者Kaschmir
相关产品推荐
相关产品推荐

