我有一个父子关系列表,其中结构不是真正的树。一些父母可以生很多孩子,也有一些孩子可以有一个以上的父母。
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的所有子代?
谢谢!
答案 0 :(得分: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}}