如何展开内嵌树结构的DataFrame 完成依赖列数值化
问题描述
现有一个存储层级依赖关系的DataFrame df1,结构为类别、类型、依赖类别三列,样例数据如下:
Category Type Dependent-Category 0 1 ~ A 1 1 ~ B 2 1 ~ C 3 1 ~ 14 4 1 ~ D 5 1 P NaN 6 A ~ C 7 A ~ D 8 A ~ 3 9 A P NaN 10 B ~ D 11 B ~ C 12 B ~ 12 13 B P NaN 14 C ~ D 15 C ~ 9 16 C P NaN 17 D ~ 12 18 D ~ 3 19 D ~ 8 20 D P NaN
其中字母类别的依赖存在嵌套:
- D类的依赖全为数值,无嵌套
- C类依赖D类和数值9
- B类依赖C、D类和数值12
- A类依赖C、D类和数值3
- 顶层类1依赖A、B、C、D类和数值14
需求是递归展开所有嵌套的类别依赖:如果某行的Dependent-Category是字母类别,就将该行替换为对应类别的所有依赖行,直到最终结果的Dependent-Category列仅包含数值和NaN。
实现代码
核心思路是先构建类别到自身依赖行的映射,再递归展开每个非数值依赖,加遍历标记避免循环依赖导致死循环:
import pandas as pd import numpy as np # 构建类别和对应行的映射 cat_row_map = {cat: grp.to_dict("records") for cat, grp in df1.groupby("Category")} def expand(target_cat, seen=None): if seen is None: seen = set() # 防止循环依赖重复遍历 if target_cat in seen: return [] seen.add(target_cat) result = [] for row in cat_row_map[target_cat]: dep_val = row["Dependent-Category"] # 依赖是数值或空值直接保留 if pd.isna(dep_val) or str(dep_val).isdigit(): result.append(row.copy()) # 依赖是嵌套类别则递归展开 else: sub_rows = expand(dep_val, seen.copy()) # 展开后的行归属到当前上层类别 for r in sub_rows: r["Category"] = target_cat result.extend(sub_rows) return result # 示例:展开顶层类别1,需要展开其他类别直接替换参数即可 expanded_data = expand("1") final_df = pd.DataFrame(expanded_data).drop_duplicates().reset_index(drop=True)
结果说明
执行后得到的final_df即为完全展开的结果,所有字母类别依赖都会被替换为底层的数值依赖,同时自动去重重复的依赖条目。如果需要展开多个顶层类别,循环调用expand函数后合并结果即可。
内容的提问来源于stack exchange,提问作者user11555536
相关产品推荐
相关产品推荐

