【问题标题】:Find all the ancestors of leaf nodes in a tree with pandas用 pandas 查找树中所有叶子节点的祖先
【发布时间】:2018-12-26 18:37:53
【问题描述】:

我有一个包含两列“父”和“子”的表。这是从 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']})

给出输出数据框(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']})

【问题讨论】:

    标签: python python-3.x pandas dataframe tree


    【解决方案1】:

    这可以使用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         
    

    【讨论】:

    • 这很有效,非常感谢。但是,对于我的数据,存在一个问题。运行上面的代码时,“parent_1”并不总是在 parent_1 列中。这会产生一个问题,因为我需要过滤掉“parent_1”数据以确保我的顶级,因为我无法从初始数据中过滤子/父数据。有没有办法确保父标签的顺序都正确?
    • @rgh_dsa 您可以使用 python3.6 来排序集合和字典。在那种情况下,我认为第一列应该代表最顶层的祖先。
    • 我仍然有这个问题。我需要在名为“ZF_ALLACCOUNTS”的案例中过滤特定的“父级”。由于一切都乱了套,我只能这样做:solution[solution.apply(lambda row: row.astype(str).str.contains('ZF_ALLACCOUNTS', case=False).any(), axis=1)] .但是......为了我的需要,我需要为父母正确的订单。你能指点我其他的方向来帮忙吗?谢谢!
    • @rgh_dsa 我有一个想法:您可以topologically sort 您的图表以获取已排序节点的列表,然后您可以按照父节点在排序列表中出现的顺序对其进行排序。这听起来不错?
    • 是的!如果出现任何其他问题,我会尝试并发表评论。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-16
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 2019-06-25
    相关资源
    最近更新 更多