【问题标题】:Find all children of top parent in python在python中查找顶级父母的所有孩子
【发布时间】:2018-07-25 21:12:35
【问题描述】:

我有一个父子关系列表,其中结构不是真正的树。有些父母可以有很多孩子,也有些孩子可以有多个父母。

import pandas as pd    
df = pd.DataFrame([[123,234],[123,235],[123,236],[124,236],[234,345],[236,346]], columns=['Parent','Child'])*

我想将所有孩子归为特定祖先。从数据来看:

123,234,235,236,345,346
124,235,346

应该是正确的组。

我试过了:

parents = set()
children = {}
for p, c in df.to_records(index=False).tolist():
    parents.add(p)
    children[c] = p


def getAncestors(p):
    return (getAncestors(children[p]) if p in children else []) + [p]

但在 346 上它只返回一组。

另外,如何找到 123 和 124 的所有孩子?

谢谢!

【问题讨论】:

  • 你考虑过使用像 networkx 这样的库吗?
  • 确定不是任何其他节点的子节点的节点,然后从每个节点执行 DFS?
  • 其实用networkx解决了这个问题。创建了 MultiDiGraph,转换为 Graph 以创建集群,然后应用 nx.ancestors 来获取父母。感谢您为我指明这个方向!

标签: python recursion


【解决方案1】:

正如您所说,它实际上并不是一棵树,而更像是一个有向无环图,因此您不能将每个孩子都映射到一个父母;它必须是父母的名单。此外,鉴于您的用例,我建议将父母映射到他们的孩子列表。

relations = [[123,234],[234,345],[123,235],[123,236],[124,236],[236,346]]

children = {}
for p, c in relations:
    children.setdefault(p, []).append(c)
roots = set(children) - set(c for cc in children.values() for c in cc)

然后您可以使用类似于您已经拥有的递归函数将所有子节点获取到给定根节点(或任何父节点)。根本身不在列表中,但可以轻松添加。

def all_children(p):
    if p not in children:
        return set()
    return set(children[p] + [b for a in children[p] for b in all_children(a)])

print({p: all_children(p) for p in roots})
# {123: {234, 235, 236, 345, 346}, 124: {346, 236}}

【讨论】:

  • 太棒了!谢谢!我现在必须重写 getAncestors 函数以适应新的子结构。
猜你喜欢
  • 1970-01-01
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多