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

4
我有一个包含“parent”和“child”两列的表格。这是从SAP(ERP) SETNODE表格中下载的。需要在Python中创建一个数据框,使每个级别都成为其父级及其之前所有级别的单独列。
在Python 3+中。
完整关系中存在未知的(或始终变化的)级别数量,因此最大级别不能总是定义。我想创建一个完整的数据框表格,显示所有级别的所有父/子关系。现在大约有15个级别,但随着我处理的其他数据量的增加,可能会增加到20个或更多。
例如(example_df)的两列:

enter image description here

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

给出输出数据框 (solution_example):

enter image description here

solution_example = pd.DataFrame({'child':['h','f','d'],'parent_1':['a','a','a'],'parent_2':['c','c','b'],'parent_3':['f', 'none', 'none']})
1个回答

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         

@rgh_dsa,你可以使用Python3.6,其中集合和字典是有序的。在这种情况下,我认为第一列应该代表最顶层的祖先。 - cs95
我仍然遇到这个问题。我需要在我的情况下过滤特定的“父级”,名为“ZF_ALLACCOUNTS”。由于它们都是无序的,我只能这样做:solution[solution.apply(lambda row: row.astype(str).str.contains('ZF_ALLACCOUNTS', case=False).any(), axis=1)]。但是...对于我的需求,我需要正确排序的父级。您能指点我其他方向以帮助吗?谢谢! - rgh_dsa
是的!我会尝试并在出现任何其他问题时回复评论。再次感谢! - rgh_dsa
我无法让它正常工作,想知道是否有任何方法可以添加更多关于如何使用拓扑排序来实现您建议的内容的信息? - rgh_dsa
@rgh_dsa,在问题主题上草率地添加信息是不合适的,因为这会使问题变得太广泛。我的建议是开一个后续问题,询问如何按拓扑排序顺序获取祖先。 - cs95
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接