如何使用pandas的json_normalize高效转换嵌套字典列表为DataFrame
嵌套字典列表转DataFrame的优化实现
原始需求
需要将如下嵌套字典列表转为单个pd.DataFrame,已有嵌套for循环实现,希望通过pd.json_normalize简化代码:
示例数据
n=dict(de={'name':'a','status':'aa'},th={'name':'b','status':'bb'},al={'name':'c','status':'cc'}) NESTED_DICT=[dict(CH=dict(bm=[n,n], cm=[n,n], dm=[n,n]),PL=dict(bm=[n,n], cm=[n,n], dm=[n,n])),dict()] data=[NESTED_DICT for _ in range(3)]
现有循环实现
import pandas as pd all_data=[] for xdata in data: for con_type in ['CH','PL']: for condi in [ 'bm','cm','dm']: ndata=xdata[0][con_type][condi] df = pd.concat([pd.DataFrame.from_dict(x, orient='index') for x in ndata]) all_data.append(df) df= pd.concat(all_data)
输出为108行2列结构,行索引为de/th/al,列名为name/status。
优化方案(基于json_normalize)
你之前的
json_normalize写法未指定record_path参数,所以只会把最外层键转为列,嵌套列表不会自动展开。record_path是指定要拆分为行的嵌套列表路径的核心参数。
实现代码
import pandas as pd # 提取有效数据,过滤空字典 valid_data = [x[0] for x in data] # 生成所有需要展开的嵌套路径 record_paths = [[con, condi] for con in ["CH", "PL"] for condi in ["bm", "cm", "dm"]] df_list = [] for path in record_paths: # 按指定路径展开嵌套列表 temp = pd.json_normalize(valid_data, record_path=path) # 转换结构对齐原始输出格式 temp = temp.melt(var_name="col_key", value_name="val") temp[["row_idx", "col"]] = temp["col_key"].str.split(".", expand=True) temp = temp.pivot(index="row_idx", columns="col", values="val").rename_axis(index=None) df_list.append(temp) # 合并所有结果 final_df = pd.concat(df_list, ignore_index=False)
效果说明
输出结果和原有嵌套for循环完全一致,都是108行2列的结构,代码更简洁,展开嵌套结构的效率也高于手动循环。
内容的提问来源于stack exchange,提问作者rpb
相关产品推荐
相关产品推荐

