我是编程、Python 和 networkx 的新手(哎哟!),并尝试按照出色的说明 here 将四个 graphml 文件合并为一个并删除重复的节点。
但是,当有四个文件(而不是两个)要比较时,我无法弄清楚如何跟踪重复节点。我在下面编写的代码不起作用,但希望您能看到我的想法是错误的并帮助我。
# script to merge one or more graphml files into one single graphml file
# First read graphml-files into Python and Networkx (duplicate variables as necessary)
A = nx.read_graphml("file1.graphml")
B = nx.read_graphml("file2.graphml")
C = nx.read_graphml("file3.graphml")
D = nx.read_graphml("file4.graphml")
# Create a new graph variable containing all the previous graphs
H = nx.union(A,B,C,D, rename=('1-','2-','3-','4-'))
# Check what nodes are in two or more of the original graphml-files
duplicate_nodes_a_b = [n for n in A if n in B]
duplicate_nodes_b_c = [n for n in B if n in C]
duplicate_nodes_c_d = [n for n in C if n in D]
all_duplicate_nodes = # How should I get this?
# remove duplicate nodes
for n in all_duplicate nodes:
n1='1-'+str(n)
n2='2-'+str(n)
n3='3-'+str(n)
n4='4-'+str(n)
H.add_edges_from([(n1,nbr)for nbr in H[n2]]) # How can I take care of duplicates_nodes_b_c, duplicates_nodes_c_d?
H.remove_node(n2)
# write the merged graphml files-variable into a new merged graphml file
nx.write.graphml(H, "merged_file.graphml", encoding="utf-8", prettyprint=True)
最佳答案
首先,请注意,您使用 nx.union
的方式不是您想要的。您确实需要仅用两个图表来调用它。但是,如何处理重复项会变得很复杂,因为您必须考虑所有可能的图对来了解如何复制节点。
相反,让我们更直接地计算每个节点出现的图表数量。使用计数器
很容易:
import collections
ctr = collections.Counter()
for G in [A, B, C, D]:
ctr.update(G)
现在使用计数器确定哪些节点只出现一次:
singles = {x for (x,n) in ctr.viewitems() if n == 1}
利用这组节点,我们可以计算仅包含不重复节点的子图:
E = nx.union(A.subgraph(singles), B.subgraph(singles))
F = nx.union(C.subgraph(singles), D.subgraph(singles))
H = nx.union(E, F)
图表H
将所有四个初始图表合并并删除了重复项。
我展示的方法会生成几个中间图,因此对于大型输入图,您可能会遇到内存问题。如果是这样,可以采用类似的方法来确定重复节点的集合,从原始图中删除这些节点,然后找到并集而不保留所有中间节点。它看起来像:
import collections
import networkx as nx
ctr = collections.Counter()
for G in [A, B, C, D]:
ctr.update(G)
duplicates = {x for (x,n) in ctr.viewitems() if n > 1}
H = nx.Graph()
for G in [A, B, C, D]:
G.remove_nodes_from(duplicates) # change graphs in-place
H = nx.union(H, G)
这两种方法都利用了 NetworkX 函数通常允许给出额外节点并默默忽略的方式。
关于python - 将多个 graphml 文件与 networkx 合并并删除重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17168456/