删除嵌套数据的重复项(图表)

drop duplicates with nested data (graph)

我有以下映射 table:


示例数据:

import pandas as pd
from numpy import nan
d = {'start': {0: 4, 1: 3, 2: 2, 3: 1, 4: 12, 5: 11, 6: 23, 7: 22, 8: 21}, 'name': {0: 'Vitamin',  1: 'Vitamin D',  2: 'Vitamin D3',  3: 'Colecalciferol',  4: 'Vitamin D2',  5: 'Ergocalcifero',  6: 'Vitamin K',  7: 'Vitamin K2',  8: 'Menachinon'}, 'end': {0: nan,  1: 4.0,  2: 3.0,  3: 2.0,  4: 3.0,  5: 12.0,  6: 4.0,  7: 23.0,  8: 22.0}}
df = pd.DataFrame(d)

l1 = ['Colecalciferol', 'Vitamin D']
l2 = ['Colecalciferol', 'Ergocalcifero', 'Vitamin D3']

预期输出:

l1 = ['Colecalciferol']
l2 = ['Colecalciferol', 'Ergocalcifero']

我试过的:

import networkx as nx
G = nx.Graph()
G = nx.from_pandas_edgelist(df, 'start', 'end', create_using=nx.DiGraph())
T = nx.dfs_tree(G, source=1).reverse()

print(list(T))
# [1, 2.0, 3.0, 4.0, nan]

本质上是显示一个术语的后继者,这里是开始 1:'Colecalciferol',但实际上我认为我需要一个术语的祖先,而不是后继者。


目标:

你非常接近!这是使用图形方法的一种方法:我们只需检查节点是否有任何前任,如果有,则意味着它不是最低级别的术语,我们不想保留它。

import networkx as nx
G = nx.Graph()
G = nx.from_pandas_edgelist(df, 'start', 'end', create_using=nx.DiGraph())

filtered_l1 = []
for elmt in l1:
    node = int(df[df.name == elmt].start)
    if list(G.predecessors(node)) == []:
        filtered_l1.append(elmt)
print(filtered_l1)

上面的for循环可以被压缩成一行:[x for x in l1 if list(G.predecessors(int(df[df.name == x].start))) == []]

一种完全消除对 networkx 依赖的更简单方法是简单地检查产品的 start 是否是任何产品的 end,在这种情况下它不是底层,我们希望将其过滤掉:

all_ends = df.end.unique()
filtered_l1 = [x for x in l1 if int(df[df.name == x].start) not in all_ends]