【问题标题】:Read data from a pandas DataFrame and create a tree using anytree in python从 pandas DataFrame 读取数据并使用 python 中的 anytree 创建树
【发布时间】:2020-09-27 04:24:56
【问题描述】:

有没有办法从 pandas DataFrame 中读取数据并使用 anytree 构造一棵树?

Parent Child
A      A1
A      A2
A2     A21

我可以使用静态值来做到这一点,如下所示。但是,我想通过使用 anytree 从 pandas DataFrame 读取数据来自动执行此操作。

>>> from anytree import Node, RenderTree
>>> A = Node("A")
>>> A1 = Node("A1", parent=A)
>>> A2 = Node("A2", parent=A)
>>> A21 = Node("A21", parent=A2)

输出是

A
├── A1
└── A2
    └── A21

这个问题,尤其是 ANSWER 已被采纳,抄袭自:

Read data from a file and create a tree using anytree in python

非常感谢@Fabien N

【问题讨论】:

    标签: python pandas anytree


    【解决方案1】:

    如果不存在,首先创建节点,将它们的引用存储在字典nodes 中以供进一步使用。必要时为孩子更换父母。我们可以通过查看Parent 值不在Child 值中的内容来推导树木森林的根,因为父节点不是任何节点的子节点,它不会出现在Child 列中。

    def add_nodes(nodes, parent, child):
        if parent not in nodes:
            nodes[parent] = Node(parent)  
        if child not in nodes:
            nodes[child] = Node(child)
        nodes[child].parent = nodes[parent]
    
    data = pd.DataFrame(columns=["Parent","Child"], data=[["A","A1"],["A","A2"],["A2","A21"],["B","B1"]])
    nodes = {}  # store references to created nodes 
    # data.apply(lambda x: add_nodes(nodes, x["Parent"], x["Child"]), axis=1)  # 1-liner
    for parent, child in zip(data["Parent"],data["Child"]):
        add_nodes(nodes, parent, child)
    
    roots = list(data[~data["Parent"].isin(data["Child"])]["Parent"].unique())
    for root in roots:         # you can skip this for roots[0], if there is no forest and just 1 tree
        for pre, _, node in RenderTree(nodes[root]):
            print("%s%s" % (pre, node.name))
    

    结果:

    A
    ├── A1
    └── A2
        └── A21
    B
    └── B1
    

    更新打印特定根目录:

    root = 'A' # change according to usecase
    for pre, _, node in RenderTree(nodes[root]):
        print("%s%s" % (pre, node.name))
    

    【讨论】:

    • 优秀的@Suparshva!因为有一大片森林,我们如何修改代码以根据父级的用户输入只打印一棵树?顺便说一句,一旦我为我的具体案例成功采用它,我会立即将其标记为答案。
    • @TendaiM 您可以删除外部for root in roots: 并使用您要查找的根键直接分配root 变量。已添加示例。
    • 谢谢@Suparshva。这个答案很完美,完全符合医生的要求。
    • 欢迎,很高兴它有帮助!
    【解决方案2】:

    详情请参考@Fabian N 在Read data from a file and create a tree using anytree in python 的回答。

    以下是采用他对外部文件与 pandas DataFrame 一起使用的答案:

        df['Parent_child'] = df['Parent'] + ',' + df['child'] # column of comma separated Parent,child
    
        i = 0
        for index, row in df.iterrows():
            if row['child']==row['Parent']:  # I modified the DataFrame by concatenating a 
                                             # dataframe of all the roots in my data, then 
                                             # copied in into both parent and child columns.  
                                             # This can be skipped by statically setting the 
                                             # roots, only making sure the assumption 
                                             # highlighted by @Fabien in the above quoted 
                                             # answer still holds true (This assumes that the 
                                             # entries are in such an order that a parent node 
                                             # was always introduced as a child of another 
                                             # node beforehand)
    
                root = Node(row['Parent'])
                nodes = {}
                nodes[root.name] = root
                i=i+1
            else:
                line = row['Parent_child'].split(",")
                name = "".join(line[1:]).strip()
                nodes[name] = Node(name, parent=nodes[line[0]])
                #predecessor = df['child_Parent'].values[i]
                i=i+1
                    
        for pre, _, node in RenderTree(root):
            print("%s%s" % (pre, node.name))
    

    如果有更好的方法来实现上述目标,请发布答案,我会接受它作为解决方案。

    非常感谢@Fabian N。

    【讨论】:

    • 参考@Suparshva 接受的答案。这比我的建议要好得多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-29
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    相关资源
    最近更新 更多