Python中深度嵌套JSON规范化错误生成数百列,求正确方案
解决深层嵌套JSON的扁平化问题(适配SQL导入)
我完全懂你的困扰——直接用json_normalize要么只拿到最外层的3列,要么递归展开出几百列根本没法用。咱们得针对性地拆解这个JSON的结构,只把核心数据展开,同时保留必要的上层关联信息,这样得到的DataFrame既清晰又适合导入SQL。
先分析你的JSON结构
你的数据是三层嵌套的核心结构:
- 最外层:
href、items(大数组,每个元素是一组车辆分类)、errors - 中间层(外层
items的元素):href、count、items(子数组,每个元素是具体的车辆数据) - 核心层(中间层
items的元素):包含车辆描述description、定价adjustedPricing、wholesale等关键字段
我们的目标是把核心层的每条车辆数据作为一行,同时带上中间层的分类信息,避免冗余展开。
分步实现代码
假设你的JSON数据已经加载到变量raw_data中,咱们一步步来:
1. 先展开外层的items数组
首先把最外层的items拆成单独的行,保留外层的href和errors作为关联信息:
import pandas as pd # 第一步:展开外层items,保留外层的href和errors outer_df = pd.json_normalize( raw_data, record_path='items', meta=['href', 'errors'], meta_prefix='outer_' )
这一步得到的outer_df里,每一行对应一个中间层的分类,包含outer_href、outer_errors、href(中间层的href)、count(中间层的count),还有items(核心车辆数据的数组)。
2. 展开核心车辆数据数组
接下来把中间层的items数组展开,同时带上所有上层的关联信息,并且合理处理嵌套字典(比如description、adjustedPricing):
# 第二步:展开核心车辆数据,带上所有上层meta信息 final_df = pd.json_normalize( outer_df.to_dict('records'), record_path='items', meta=['outer_href', 'outer_errors', 'href', 'count'], meta_prefix='category_', sep='_' # 用下划线分隔嵌套字段,避免列名混乱 )
这一步的关键是:
record_path='items'指定要展开的核心数组meta参数带上所有需要保留的上层字段,并用meta_prefix加前缀区分sep='_'让嵌套字段(比如description.year)变成description_year,列名清晰且符合SQL命名规范
3. 整理数据(可选但推荐)
最后可以清理掉不需要的字段(比如outer_errors如果全是空的),并调整列名更友好:
# 清理冗余字段,比如errors全为0的话可以删掉 final_df = final_df.drop(columns=['category_outer_errors']) # 调整列名,比如把category_href改成category_url final_df = final_df.rename(columns={ 'category_href': 'category_url', 'category_count': 'category_vehicle_count', 'outer_href': 'root_url' })
最终效果
处理后的final_df每一行对应一条具体的车辆数据,列名类似:root_url、category_url、category_vehicle_count、href、description_year、description_make、adjustedPricing_wholesale_average、wholesale_average...
这样的结构完全适合导入SQL:
- 没有冗余的嵌套数组
- 列名符合SQL命名规则(用下划线,无特殊字符)
- 所有关联信息都保留在每行中,不需要额外的关联表(如果需要范式化也可以拆分,但这个结构已经满足大部分导入需求)
为什么之前的方法不行?
- 直接
pd.json_normalize(raw_data)只会处理最外层,所以只返回3列; - 如果用递归全展开的方法,会把所有嵌套的键都拆成独立列,包括很多重复或无关的字段,导致几百列没法用;
- 咱们的方法是定向展开,只把核心数据拆成行,同时保留必要的上层关联信息,平衡了扁平化和可读性。
内容的提问来源于stack exchange,提问作者morgan

