如何基于pandas DataFrame值生成完美树结构全组合数据
问题说明
现有如下结构的pandas DataFrame:
name1 name2 name3 0 1 2 3 1 1 2 1 2 1 3 4
需要将其转换为完美树结构:所有已存在的(name1, name2)上层组合,都要关联name3列的全部去重值,最终预期输出为:
name1 name2 name3 0 1 2 1 1 1 2 3 2 1 2 4 3 1 3 1 4 1 3 3 5 1 3 4
对应树结构示意:
1 / \ / \ / \ / \ 2 3 /|\ /|\ / | \ / | \ 1 3 4 1 3 4
原有实现靠append、repeat反复拼接数据,逻辑冗长,需要更简洁的pandas原生实现。
实现方案
不需要手写循环拼接,pandas原生就支持这类交叉组合场景,推荐两种简洁写法:
- 方法1:交叉合并(推荐,可读性最高、性能稳定)
核心思路是拆分上层维度、叶子维度两个部分,直接用官方提供的笛卡尔积合并接口生成结果,代码如下:
# 提取原数据中所有存在的上层节点组合,去重 upper_nodes = df[["name1", "name2"]].drop_duplicates() # 提取叶子节点name3的所有去重值 leaf_nodes = df[["name3"]].drop_duplicates() # 交叉合并直接生成所有组合,就是需要的完美树结构 result = upper_nodes.merge(leaf_nodes, how="cross").reset_index(drop=True)
注:how="cross"是pandas 1.2.0版本上线的官方参数,专门用于笛卡尔积合并场景,执行效率远高于手写逐行拼接。
- 方法2:迭代器生成全组合
如果使用的pandas版本较低不支持cross合并,可以用标准库itertools.product生成所有组合后直接转DataFrame:
from itertools import product # 生成(上层节点组合, 叶子节点值)的全配对 all_pairs = product( upper_nodes.itertuples(index=False, name=None), leaf_nodes["name3"].to_list() ) # 展开元组转为DataFrame result = pd.DataFrame( [(n1, n2, n3) for (n1, n2), n3 in all_pairs], columns=["name1", "name2", "name3"] )
避坑提示:不要直接对
name1、name2、name3三个字段各自的唯一值做笛卡尔积,否则会生成原数据中不存在的上层节点组合(比如凭空出现name1=1, name2=4这类无效节点),破坏原有树结构。
内容的提问来源于stack exchange,提问作者tarek sawara
相关产品推荐
相关产品推荐

