如何从多层嵌套字典创建Pandas多层索引DataFrame
多层嵌套模型评估字典构建Pandas多层索引DataFrame方案
你的原有写法仅能处理两层字典结构,无法自动递归拆解内层评估字典,可通过先递归打平嵌套键路径,再重构索引的方式实现全层级展开,以下是可直接复用的实现:
前置准备:对齐测试结构
先给出和你描述完全匹配的最小测试字典,方便调试对照:
import pandas as pd from sklearn.naive_bayes import MultinomialNB # 测试用嵌套字典,结构和你的实际数据完全对齐 all_models = { "naive_bayes": { "classifier": MultinomialNB(), "count_vect": { "accuracy": {"f1-score": 0.82, "support": 1000}, "consumer": {"precision": 0.79, "recall": 0.83, "f1-score": 0.81, "support": 420}, "deal_sites": {"precision": 0.86, "recall": 0.78, "f1-score": 0.82, "support": 310}, "macro avg": {"precision": 0.81, "recall": 0.80, "f1-score": 0.80, "support": 1000}, "weighted avg": {"precision": 0.82, "recall": 0.82, "f1-score": 0.82, "support": 1000} }, "tfidf_vect": { "accuracy": {"f1-score": 0.85, "support": 1000}, "consumer": {"precision": 0.84, "recall": 0.86, "f1-score": 0.85, "support": 420}, "deal_sites": {"precision": 0.87, "recall": 0.83, "f1-score": 0.85, "support": 310}, "macro avg": {"precision": 0.85, "recall": 0.84, "f1-score": 0.84, "support": 1000}, "weighted avg": {"precision": 0.85, "recall": 0.85, "f1-score": 0.85, "support": 1000} } } }
方案1:全层级行多层索引
所有嵌套层级都作为行索引,最内层指标值作为单列值,适合后续做筛选、聚合计算:
def flatten_nested_dict(nested_dict, parent_key_tuple=()): flat_entries = [] for key, value in nested_dict.items(): current_key_path = parent_key_tuple + (key,) # 遇到非字典值(分类器实例、数值指标)终止递归 if not isinstance(value, dict): flat_entries.append((current_key_path, value)) else: flat_entries.extend(flatten_nested_dict(value, current_key_path)) return flat_entries # 打平后转带多层索引的Series,再转DataFrame flat_data = dict(flatten_nested_dict(all_models)) row_multi_index_df = pd.Series(flat_data, name="metric_value").to_frame() # 给每层索引命名,方便后续使用 row_multi_index_df.index.names = [ "model_name", "vectorize_or_clf", "category_or_agg", "specific_metric" ]
输出的索引从外到内依次对应:模型名、配置项(分类器实例/各类向量化方案名)、分组(业务类别/accuracy/聚合指标)、具体指标(precision/recall/f1-score/support),无残留嵌套字典。
方案2:内层指标作为列(更符合评估表阅读习惯)
如果想要最内层的precision/recall等指标作为列,外层层级作为行索引,只需要对打平后的Series做一次unstack即可:
# 最内层指标放列 col_metric_df = pd.Series(flat_data).unstack(level=-1) col_metric_df.index.names = ["model_name", "vectorize_or_clf", "category_or_agg"]
如果需要列方向多层索引,只需要指定unstack的层级即可,比如把「分组+具体指标」都放到列方向:
multi_col_df = pd.Series(flat_data).unstack(level=[-2, -1]) multi_col_df.index.names = ["model_name", "vectorize_or_clf"]
原有写法问题说明
pd.DataFrame.from_dict(all_models, orient="index").stack().to_frame() 仅能自动拆解两层字典结构,第二层中存储的评估结果本身仍是字典类型,pandas不会自动递归展开,因此单元格中会残留未拆解的字典对象,必须先通过递归把所有嵌套路径转换为元组键,再构建DataFrame才能实现全层级展开。
内容的提问来源于stack exchange,提问作者ROO
相关产品推荐
相关产品推荐

