2012-06-14 85 views
8

我想要處理一個具有數億個節點的超大型NetworkX圖形對象。我希望能夠將它寫入文件,以便不消耗我所有的計算機內存。但是,我需要不斷搜索現有節點,更新邊緣等。讀/寫NetworkX圖形對象

有沒有一個很好的解決方案?我不知道它將如何與所提供的任何關於http://networkx.lanl.gov/reference/readwrite.html

唯一的解決方案,我能想到的是給每個節點存儲與在文件系統中的其他節點引用一個單獨的文件中的文件格式的工作 - 這樣,打開一個節點進行檢查不會使存儲器過載。是否有大量數據的現有文件系統(例如PyTables)在不編寫自己的樣板代碼的情況下執行此操作?

回答

2

如果你已經建立了這個作爲NetworkX圖,然後將已經在內存中。對於這個龐大的圖表,我猜測你必須做一些類似於你對單獨文件的建議。但是,我沒有使用單獨的文件,而是使用數據庫來存儲每個節點之間的多對多連接。換句話說,你需要一個節點表和一個邊緣表,然後查詢一個特定節點的鄰居,你可以查詢任何一邊有特定節點的邊。這應該很快,但我不確定您是否能夠利用NetworkX的分析功能,而無需先在內存中構建整個網絡。

+0

感謝Luis。Essentially我存儲在一個數據庫中,但是,查詢節點來獲取鄰居是非常昂貴的,我只能想象Google的服務器是什麼樣的... – ejang

+0

如果圖形已經在RAM中,那麼爲什麼要序列化它是一個問題?磁盤空間比RAM便宜)或者NetworkX有某種內部方法來壓縮表示,並且在序列化過程中會彈出?我很好奇 – user

+0

我認爲這個問題並沒有把重點放在序列化上,而是把它保存在一個結構中這將允許有效的查詢。這是我對數據庫的建議來自何處。 – LuisZaman

18

第一次嘗試pickle;它旨在序列化任意對象。

創建DiGraph和序列化到一個文件的一個例子:

import pickle 
import networkx as nx 

dg = nx.DiGraph() 
dg.add_edge('a','b') 
dg.add_edge('a','c') 
pickle.dump(dg, open('/tmp/graph.txt', 'w')) 

從文件加載一個DiGraph的一個例子:

import pickle 
import networkx as nx 

dg = pickle.load(open('/tmp/graph.txt')) 
print dg.edges() 

輸出:

[('a', 'c'), ('a', 'b')] 

如果這是不夠高效的,我會寫你自己的例程序列化:

  1. 邊緣和
  2. 節點(如果一個節點是入射到無毛邊)。

請注意,儘可能使用列表推導可能會更有效率(而不是標準的循環)。

如果是不是足夠有效的,我會打電話給一個C++程序從內部的Python: http://docs.python.org/extending/extending.html

+2

+1泡菜是一件好事,以前從未聽說過,謝謝! – Eduardo

+1

Pickle爲對象生成MASSIVE文件,如果這已經是一個大型網絡,pickle幾乎肯定不會起作用。由於許多其他原因,這是一個很好的和未被充分利用的軟件包! – LuisZaman

+0

@LuisZaman我知道你的意思。在那種情況下,我會手動序列化邊和節點(如上所述)。但是如果圖形已經在RAM中,那麼如果泡菜膨脹得不適合磁盤,我會感到非常驚訝。 – user