如何将多层嵌套字典列表用Pandas转换为指定格式的DataFrame
错误原因说明
你之前调用pd.json_normalize(records, 'episodes')报KeyError,是因为episodes字段并不在列表元素的根层级,而是嵌套在episodeStream字典下,需要给record_path传入完整的层级路径列表['episodeStream', 'episodes']才能正确定位到目标数组。
实现方案
这里提供两种可直接使用的实现方式,输出完全匹配你需要的结构:
方案1:循环遍历(逻辑直观,不易出错)
适合数据量在十万条级以内的场景,代码逻辑简单好调试:
import pandas as pd # records 是你读取到的原始嵌套字典列表 processed_data = [] for stream_idx, stream_dict in enumerate(records): # 遍历当前dict下的所有episode for ep_idx, episode in enumerate(stream_dict["episodeStream"]["episodes"]): processed_data.append({ "episodeStreamId": stream_idx, "episodesId": ep_idx, "timestamp": episode["timestamp"], "data": episode["data"] }) # 直接生成DataFrame df = pd.DataFrame(processed_data)
方案2:json_normalize原生实现(性能更高)
适合数据量较大的场景,利用pandas原生方法减少Python循环开销:
import pandas as pd # 直接拉平episodes层级 df = pd.json_normalize( records, record_path=["episodeStream", "episodes"], errors="ignore" ) # 生成episodeStreamId:对应原始列表中每个dict的序号 episode_cnt_per_stream = [len(s["episodeStream"]["episodes"]) for s in records] cum_cnt = [0] + [sum(episode_cnt_per_stream[:i+1]) for i in range(len(episode_cnt_per_stream))] df["episodeStreamId"] = pd.cut(df.index, bins=cum_cnt, labels=range(len(episode_cnt_per_stream)), include_lowest=True) # 生成episodesId:对应每个episode在所属stream内的序号 df["episodesId"] = df.groupby("episodeStreamId").cumcount() # 按需求调整列顺序 df = df[["episodeStreamId", "episodesId", "timestamp", "data"]]
后续扩展说明
如果后续需要把data字段的嵌套内容也展开为单独列,可以对df["data"]再做一次pd.json_normalize,然后和原表拼接即可。
内容的提问来源于stack exchange,提问作者bhdrozgn
相关产品推荐
相关产品推荐

