2016-09-18 62 views
0

我想比较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对象的副本?

+0

[Networkx copy clarification]的可能副本(http://stackoverflow.com/questions/29854387/networkx-copy-clarification) – Anaphory

回答

1

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

copy方法文档

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

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

数据参考(浅) - 对于浅表副本(with_data =假)的 图结构是复制的,但边缘,节点和图形属性类型的字典 是那些在原始图的引用。这样可以节省时间和内存,但如果更改一个 图中的属性并导致另一个属性更改,可能会导致混淆。

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']})] 
+0

从2.0版开始,这似乎不再成立。 – xuhdev

-1

也请注意,如果您networkx图包含的对象...的对象,甚至deepcopy的是行不通的。它会返回一个错误,说明层次太多。

通常情况下,我会考虑图表中究竟是什么感兴趣的东西,只需创建一个新的图表。