如何复制networkx Graph而不是deepcopy?

时间:2016-09-18 08:55:20

标签: networkx deep-copy

我想比较函数调用networkx.Graph(带副作用)之前n对象d(n)的状态与之后的状态。

有可变对象节点属性,例如n.node[0]['attribute'],我想比较。

显然,

before = n
d()
after = n
assert id(before.node[0]['attribute']) == id(after.node[0]['attribute'])

成功,因为

before == after

但如果我设置before=n.copy(),则会生成一份深层副本,因此id(before.node[0]['attribute']) != id(after.node[0]['attribute'])。如何在不复制所有节点属性对象的情况下获取Graph对象的副本?

3 个答案:

答案 0 :(得分:2)

调用copy方法会提供深层复制。新图的所有属性都是原始图的副本。调用构造函数(例如Graph(G))会给出一个浅复制,其中复制了图形结构,但数据属性是原始图形中的引用。

来自copy方法文档

  

所有副本都会重现图形结构,但数据属性可能会重现   以不同的方式处理。图表有四种类型的副本   人们可能想要的。

     

Deepcopy - 默认行为是图形的“深度复制”   结构以及所有数据属性和它们可能包含的任何对象   包含被复制。整个图形对象是新的,因此可以进行更改   副本不会影响原始对象。

     

数据引用(浅) - 对于浅拷贝(with_data = False)   复制了图形结构,但边缘,节点和图形属性都是双重的   是对原始图中的那些的引用。这节省了时间和   内存,但如果您更改一个属性可能会导致混淆   图表,它改变了另一个属性。

In [1]: import networkx as nx

In [2]: G = nx.Graph()

In [3]: G.add_node(1, color=['red'])

In [4]: G_deep = G.copy()

In [5]: G_deep.node[1]['color'].append('blue')

In [6]: list(G.nodes(data=True))
Out[6]: [(1, {'color': ['red']})]

In [7]: list(G_deep.nodes(data=True))
Out[7]: [(1, {'color': ['red', 'blue']})]

In [8]: G_shallow = nx.Graph(G)

In [9]: G_shallow.node[1]['color'].append('blue')

In [10]: list(G.nodes(data=True))
Out[10]: [(1, {'color': ['red', 'blue']})]

In [11]: list(G_shallow.nodes(data=True))
Out[11]: [(1, {'color': ['red', 'blue']})]

答案 1 :(得分:0)

尝试一下:

G = # your graph
G2 = nx.Graph() # or whatever type of graph `G` is
G2.add_edges_from(G.edges())

答案 2 :(得分:-1)

另请注意,如果您的networkx图包含对象的对象...,即使深度复制也无效。它会返回一个错误,即有太多级别。

通常,我会想到图中究竟有什么兴趣,然后用它来创建一个新图。