<p>子树和从networkX对象读取都是正常的,问题是您将所有子树直接添加到原始的<code>tree</code>实例中。在ete3中,<code>Tree</code>类是<a href="http://etetoolkit.org/docs/latest/tutorial/tutorial_trees.html#understanding-ete-trees" rel="nofollow noreferrer">in fact just a Node</a>(包括指向其后代的指针,如果有的话),因此<code>tree.add_child</code>直接向根节点添加新的子节点/子树。在</p>
<p>您应该做的是<a href="http://etetoolkit.org/docs/latest/tutorial/tutorial_trees.html#browsing-trees-traversing" rel="nofollow noreferrer">iterate over the leaves of ete tree</a>,找到<code>node.name == parent</code>的那个,并将所有子元素附加到它上。另外,您应该逐个附加它们,而不是预先生成子树。否则,您将获得具有单个父节点和单个子节点的附加内部节点。在</p>
<h2>编辑:</h2>
<p>代码的第二个版本几乎是正确的,但是您没有考虑到如果根不是它们的实际父节点,则节点永远不会被附加到树(<em>ie</em>root)。这可能就是为什么您将<code>lvl-1</code>作为一个单独的节点,而不是其他节点的父节点。另外,我不确定networkX图的遍历顺序,这可能很重要。更安全(如果更丑)的版本应该是这样的:</p>
<pre><code># Setting up a root node for lvl-1 to attach to
tree.add_child(name='input')
# A copy in a list, because you may not want to edit the original graph
edges = list(graph.edges)
while len(edges) > 0:
for parent, child in edges:
# check if this edge's parent is in the tree
for leaf it tree.get_leaves():
if leaf.name == parent:
# if it is, add child and thus create an edge
leaf.add_child(name=child)
# Wouldn't want to add the same edge twice, would you?
edges.remove((parent, child))
# Now if there are edges still unplaced, try again.
</code></pre>
<p>可能有几个打字错误,而且绝对是超慢。从边缘计数到O(n**2)或更糟的东西,包括所有的迭代和列表删除。可能有一种方法可以将图从根遍历到叶,这不需要边列表的副本(只需一次迭代即可工作)。但它最终会产生一棵正确的树。在</p>