将几个graphml文件与networkx合并并删除重复项

时间:2013-06-18 12:06:38

标签: python python-2.7 networkx graphml

我是编程,Python和networkx的新手(哎哟!),并尝试将四个graphml文件合并为一个并删除重复的节点,遵循优秀的说明here

但是,当有四个要比较的文件而不是两个时,我无法弄清楚如何跟踪重复的节点。我在下面写的代码不会起作用,但你可以希望看到我的错误并帮助我。

# 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)

2 个答案:

答案 0 :(得分:2)

首先,请注意您使用nx.union的方式不是您想要的。你真的需要用两个图表来调用它。但是如何处理重复项会以这种方式变得复杂,因为您必须考虑所有可能的图形对,以查看节点是如何复制的。

相反,让我们更直接,只计算每个节点出现的图表数量。使用Counter

很容易
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函数通常允许给出额外节点并静默忽略的方式。

答案 1 :(得分:1)

如果graphml文件很简单(没有权重,属性等),那么在文本级别工作可能更容易。例如,

cat A.graphml B.graphml C.graphml | sort -r | uniq > D.graphml

这将保留三个graphml文件中的唯一节点和边集。您可以稍后使用文本编辑器重新排列D.graphml中的<graph></graph><graphml ...></graphml>标记。