2016-09-18 48 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的是行不通的。它會返回一個錯誤,說明層次太多。

通常情況下,我會考慮圖表中究竟是什麼感興趣的東西,只需創建一個新的圖表。