我能够想出一些东西。我不知道它是否是最好/最快/最有效的,但它确实有效。
首先,使用上面的脚本创建父子关系(如果尚未存在),并添加一个名为 level 的列,用于描述部件在树 0 中的最高级别。那么……
#this part of the script will create a row for each branch of the tree
dfsort = df[df['level'] == 0][['parent_id','child_id']].rename(columns = {'parent_id':f'level 0', 'child_id':f'level 1'})
for i in sorted(df['level'].unique()[1:]):
df1 = df[df['level'] == i][['parent_id','child_id']].rename(columns = {'parent_id':f'level {i}', 'child_id':f'level {i+1}'})
dfsort = pd.merge(dfsort,
df,
how = 'left', on = [f'level {i}']
dfsort = dfsort[sorted(dfsort.columns)]
#create a node column to drop duplicates on (in case any similar parent child relations are used across multiple higher level parts
dfsort['Node'] = dfsort.astype(str).apply(list, axis =1 )
dfsort['Node'] = dfsort['Node'].apply(lambda x: [i for i in x if i != 'nan'])
#now that you have this relationship you can break it out in the correct order using another for loop
dfsort2 = pd.DataFrame()
#append a new dataframe with the parent childs from above table one row at a time
for i in range(len(dfsort)):
for l in range(len(dfsort.iloc[i][:-1])):
df = dfsort.iloc[[i]][[f'level {i}',f'level {i-1}', 'Node']].rename(columns = {f'level {l}':'parent_id', f'level {l+1}'})
df['level'] = l
dfsort2 = pd.concat([dfsort2, df])
dfsort2 = dfsort[(dfsort2['parent_id'].notna()) &
(dfsort2['child_id'].notna())]
dfsort2 ['order node index'] = dfsort2 .apply(lambda x: x['Node'].index(x['child_id']), axis = 1)
dfsort2 ['Query Node'] = dfsort2 .apply(lambda x: x['Node'][:x['order node index'] + 1], axis = 1).apply(lambda x: ",".join(x))
del dfsort2 ['order node index'], dfsort2 ['Node']
dfsort2 = dfsort2 .drop_duplicates()