如何无需预定义层级/字段,完全展平DataFrame中的JSON列?
解决DataFrame嵌套JSON列的完全展平问题
核心思路
要实现无需预定义JSON深度和字段的展平,核心是通过递归遍历每个JSON对象的键值对,记录完整的层级路径,再将扁平化后的键值对转换为新的DataFrame,最后与原DataFrame的非JSON列合并。
具体实现(Python + Pandas)
1. 编写递归扁平化函数
这个函数会自动拆解嵌套结构,用下划线拼接完整路径作为键:
def flatten_json(obj, parent_key='', sep='_'): items = [] for k, v in obj.items(): new_key = f"{parent_key}{sep}{k}" if parent_key else k if isinstance(v, dict): items.extend(flatten_json(v, new_key, sep=sep).items()) else: items.append((new_key, v)) return dict(items)
2. 处理DataFrame中的JSON列
先将JSON格式的字符串转为可操作的字典(示例中用ast.literal_eval兼容非标准JSON,比如单引号格式),再应用扁平化函数:
import pandas as pd import ast # 构造示例DataFrame(修正格式) df = pd.DataFrame({ 'A': [1], 'B': [2], 'C': ["{'b':1,'c':2,'d':{'r':1,'t':{'y':0}}}"], 'D': ["{'v':9}"] }) # 字符串转字典 df['C'] = df['C'].apply(ast.literal_eval) df['D'] = df['D'].apply(ast.literal_eval) # 对JSON列应用扁平化,生成新DataFrame(添加原列名作为路径前缀) flattened_c = df['C'].apply(lambda x: flatten_json(x, parent_key='C')).apply(pd.Series) flattened_d = df['D'].apply(lambda x: flatten_json(x, parent_key='D')).apply(pd.Series) # 合并所有列 result_df = pd.concat([df[['A', 'B']], flattened_c, flattened_d], axis=1)
3. 最终效果
处理后的result_df会生成以下列:A、B、C_b、C_c、C_d_r、C_d_t_y、D_v,完全符合你需要的完整路径列名要求。
额外处理说明
- 如果JSON中包含数组,可在扁平化函数中添加
isinstance(v, list)的判断,将数组元素按索引拼接路径(比如key_0、key_1)。 - 若JSON是标准双引号格式,用
json.loads替代ast.literal_eval即可。
内容的提问来源于stack exchange,提问作者Cranjis
相关产品推荐
相关产品推荐

