从具有父子关系的 2 列获取层次结构

问题描述 投票:0回答:1

我有一个像这样的数据框:

data = {
    'Parent': [None, None,  'A',    'B',    'C',    'I',    'D',    'F',    'G',    'H',    'Z',    'Y',    None,None,None,None,    'AA',   'BB',   'CC',   'EE',   'FF',   None,   None],
    'Child': ['A',  'B',    'D',    'D',    'D',    'C',    'E',    'E',    'F',    'F',    'G',    'H',    'Z',    'Y',    'AA',   'BB',   'CC',   'CC',   'DD',   'DD',   'DD',   'EE',   'FF']
}

df = pd.DataFrame(data)
        
   Parent Child
0    None     A
1    None     B
2       A     D
3       B     D
4       C     D
5       I     C
6       D     E
7       F     E
8       G     F
9       H     F
10      Z     G
11      Y     H
12   None     Z
13   None     Y
14   None    AA
15   None    BB
16     AA    CC
17     BB    CC
18     CC    DD
19     EE    DD
20     FF    DD
21   None    EE
22   None    FF

我想要一个像这样的输出数据框:

Expected Output

我尝试使用

networkx
包中建议的post, 这是我使用的代码

df['parent']=df['parent'].fillna('No Parent')

leaves =set(df['parent']).difference(df['child'])
g= nx.from_pandas_edgelist(df, 'parent', 'child', create_using=nx.DiGraph())
ancestors = {
    n: nx.algorithms.dag.ancestors(g, n) for n in leaves
}

df1=(pd.DataFrame.from_dict(ancestors, orient='index')
 .rename(lambda x: 'parent_{}'.format(x+1), axis=1)
 .rename_axis('child')
 .fillna('')
 )

但是我得到一个空数据框。 有没有一种优雅的方法来实现这一点?

python python-3.x pandas
1个回答
0
投票

其中一个选项是制作

from_dict
的最终DataFrame
successors

DG = nx.from_pandas_edgelist(df.fillna("#"), "parent", "child", create_using=nx.DiGraph)

DG.remove_node("#") # remove the placeholder

out = (
    pd.DataFrame.from_dict(
        {n: DG.predecessors(n) for n in DG}, orient="index"
    ).rename(columns=lambda c: f"Parent {c+1}")
)

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.