Python实现JSON半扁平化:移除父键保留嵌套值
如何实现JSON的「半扁平化」处理(仅展开顶层嵌套对象)
我明白你要的是仅展开顶层嵌套对象的半扁平化处理——也就是把Stat、Goal这些顶层键对应的字典直接拆成平级字段,而不是像之前的方法那样完全扁平化所有层级,或者给字段加列表索引前缀。下面给你两种可行的实现方式:
方法一:纯Python实现(轻量直观)
这种方法不需要依赖第三方库,直接遍历每个顶层对象,把嵌套的字典键值对合并到平级结构中:
def semi_flatten(item): flattened = {} for key, value in item.items(): # 仅处理顶层的字典类型值,直接合并键值对 if isinstance(value, dict): flattened.update(value) else: # 如果顶层值不是字典(比如列表/字符串),直接保留(可根据需求调整) flattened[key] = value return flattened # 你的原始JSON数据 original_json = [ { "Stat": { "event": "03458188-abf9-431c-8144-ad49c1d069ed", "id": "102e1bb1f28ca44b70d02d33380b13", "number": "1121", "source": "", "datetime": "2023-01-13T00:00:00Z", "status": "ok" }, "Goal": {"name": "goalname"}, "Fordel": {"company": "companyname"}, "Land": {"name": "landname"} }, { "Stat": { "event": "22222", "id": "44444", "number": "5555", "source": "", "datetime": "2023-01-13T00:00:00Z", "status": "ok" }, "Goal": {"name": "goalname2"}, "Fordel": {"company": "companyname2"}, "Land": {"name_land": "landname2"} } ] # 执行半扁平化处理 result = [semi_flatten(item) for item in original_json] print(result)
运行后就能得到你期望的结果:
[ { "event": "03458188-abf9-431c-8144-ad49c1d069ed", "id": "102e1bb1f28ca44b70d02d33380b13", "number": "1121", "source": "", "datetime": "2023-01-13T00:00:00Z", "status": "ok", "name": "goalname", "company": "companyname", "name": "landname" }, { "event": "22222", "id": "44444", "number": "5555", "source": "", "datetime": "2023-01-13T00:00:00Z", "status": "ok", "name": "goalname2", "company": "companyname2", "name_land": "landname2" } ]
方法二:用pandas实现(适合大数据量处理)
如果你的数据量较大,用pandas的json_normalize可以更高效地处理,只需要指定要展开的顶层嵌套路径,然后合并结果:
import pandas as pd # 你的原始JSON数据 original_json = [ # 同上的原始数据 ] # 初始化空DataFrame,逐个展开顶层嵌套对象并合并 df = pd.DataFrame() for top_key in original_json[0].keys(): # 展开当前顶层键对应的字典 nested_df = pd.json_normalize(original_json, record_path=top_key) df = pd.concat([df, nested_df], axis=1) # 转换为你需要的JSON格式 result = df.to_dict('records') print(result)
这个方法会把每个顶层嵌套的字典都展开成DataFrame的列,最后拼接成完整的平级结构,转成records格式后就和你期望的结果一致。
为什么之前的方法不行?
你之前用的flatten_data函数是完全扁平化所有层级的结构,并且会给列表中的元素添加索引前缀(比如0_event),这显然不符合你只展开顶层嵌套的需求。我们的方法只处理第一层的字典,直接合并键值对,避免了过度扁平化。
内容的提问来源于stack exchange,提问作者Ali Durrani
相关产品推荐
相关产品推荐

