用 pandas 查找树中叶节点的所有祖先

rgh*_*dsa 4 python tree dataframe python-3.x pandas

我有一个表,有两列:“父”和“子”。这是从 SAP (ERP) 下载的 SETNODE 表。需要在 python 中创建一个数据框,其中每个级别作为其自己的列(相对于其父级和之前的所有级别)。

在Python 3+中。

完整关系的级别数量未知(或始终变化),因此无法始终定义最大级别。我想创建一个完整的数据框表,显示所有级别的所有父/子关系。目前大约有 15 个级别,但根据我使用的其他数据,它可能会上升到 20 个或更多。

例如(example_df)的两列:

在此输入图像描述

example_df = pd.DataFrame({'parent:['a','a','b','c','c','f'],'child':['b','c','d','f','g','h']})
Run Code Online (Sandbox Code Playgroud)

给出输出数据帧(solution_example):

在此输入图像描述

solution_example = pd.DataFrame({'child':['h','f','d'],'parent_1':['a','a','a'],'parent_2':['c','c','b'],'parent_3':['f', 'none', 'none']})
Run Code Online (Sandbox Code Playgroud)

cs9*_*s95 6

这可以使用networkx库来解决。首先,从 DataFrame 构建一个有向图,然后找到叶节点的所有祖先。

import networkx as nx

leaves = set(df.child).difference(df.parent)
g = nx.from_pandas_edgelist(df, 'parent', 'child', create_using=nx.DiGraph())
ancestors = {
    n: nx.algorithms.dag.ancestors(g, n) for n in leaves
}

(pd.DataFrame.from_dict(ancestors, orient='index')
   .rename(lambda x: 'parent_{}'.format(x+1), axis=1)
   .rename_axis('child')
   .fillna(''))

      parent_1 parent_2 parent_3
child                           
h            a        c        f
g            a        c         
d            a        b         
Run Code Online (Sandbox Code Playgroud)