删除嵌套数据的重复项(图表)
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',但实际上我认为我需要一个术语的祖先,而不是后继者。
目标:
我想删除重复项,即使是 higher/lower 级术语。例如。:
'Colecalciferol' 是 'Vitamin D3' 是 'Vitamin D' .
因此,我想删除'Vitamin D'以保留信息
示例 (l1) 中最低级别的术语。
你非常接近!这是使用图形方法的一种方法:我们只需检查节点是否有任何前任,如果有,则意味着它不是最低级别的术语,我们不想保留它。
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]
我有以下映射 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',但实际上我认为我需要一个术语的祖先,而不是后继者。
目标:
我想删除重复项,即使是 higher/lower 级术语。例如。: 'Colecalciferol' 是 'Vitamin D3' 是 'Vitamin D' .
因此,我想删除'Vitamin D'以保留信息 示例 (l1) 中最低级别的术语。
你非常接近!这是使用图形方法的一种方法:我们只需检查节点是否有任何前任,如果有,则意味着它不是最低级别的术语,我们不想保留它。
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]