Поиск окончательного родителя

#python #pandas #pyspark #hierarchy

Вопрос:

Я пытаюсь найти идеального родителя с помощью Dir pandas. Но у задачи есть одна особенность, в которой график на самом деле не подходит, или я просто не знаю, как его правильно использовать. Ввод:

Ребенок Родитель Класс
1001 8888 A
1001 1002 D
1001 1002 C
1001 1003 C
1003 6666 G
1002 9999 H

Выход:

Ребенок Ultimate_Parent Класс Соединение
1001 8888 A Прямой
1001 9999 D Косвенный
1001 9999 C Косвенный
1001 6666 C Косвенный
1003 6666 G Прямой
1002 9999 H Прямой

Я делаю:

 import pandas as pd  import networx as nx  df = pd.DataFrame({'Child': ['1001', '1001', '1001', '1001', '1003', '1004'], 'Parent': ['8888', '1002', '1002', '1003', '6666', '9999'],'Class': ['A','D','C','C','G','H']})  def get_hierarchy (df):  DiG=nx.from_pandas_adgelist (df,'child','parent',create_using=nx.DiGraph())  return pd.DataFrame.from_records([(n1,n2) for n1 in DiG.nodes() for n2 in nx.ancestors(DiG, n1)], columns=['child','Ultimate_parent'])  df=df.toPandas()  df=get_hierarchy(df)  return df  

И я не могу понять, как использовать атрибут класса здесь, чтобы показать дважды 1001 с классами D и C.

Комментарии:

1. Вы путаете дочерние и родительские столбцы? Я бы ожидал, что у одного родителя много детей, но не у одного ребенка много родителей.

2. df=df.toPandas() это не имеет смысла. df уже является фреймом данных pandas

Ответ №1:

Используется G.predecessors для определения того, является ли ток Parent корнем дерева или нет. Если да, то соединение-это Direct другое соединение Indirect .

 G = nx.from_pandas_edgelist(df, source='Parent', target='Child',  create_using=nx.DiGraph)  roots = [node for node, degree in G.in_degree() if degree == 0]  ultimate_parent = [node if node in roots else list(G.predecessors(node))[0]   for node in df['Parent']]  df['Ultimate_Parent'] = ultimate_parent df['Connection'] = np.where(df['Parent'] == df['Ultimate_Parent'],  'Direct', 'Indirect')  

Выход:

 gt;gt;gt; df  Child Parent Class Ultimate_Parent Connection 0 1001 8888 A 8888 Direct 1 1001 1002 D 9999 Indirect 2 1001 1002 C 9999 Indirect 3 1001 1003 C 6666 Indirect 4 1003 6666 G 6666 Direct 5 1002 9999 H 9999 Direct