2016-05-05 22 views
1

我必須定義一個網絡,每個邊的權重必須等於每對節點之間的連接數。下面的代碼生成這樣的網絡:在networkx中,如何以矢量化的方式更新邊緣權重?

In [1]: import networkx as nx 

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

In [3]: connections = [[1,2],[2,3],[1,2],[2,1],[1,4],[2,3]] 

In [4]: for e1,e2 in connections : 
    if g.has_edge(e1,e2) : 
     g[e1][e2]['weight'] += 1 
    else : 
     g.add_edge(e1,e2,weight=1) 
    ...:   

In [5]: g.edges(data=True) 
Out[5]: [(1, 2, {'weight': 3}), (1, 4, {'weight': 1}), (2, 3, {'weight': 2})] 

在實際情況中,連接列表將包含數千對。成千上萬個這樣的列表將被生成,並且它們中的每一個都必須立即包含在網絡中並被刪除,因爲沒有內存可以將所有列表存儲在一起。

由於Python是一種解釋型語言,我不能使用「for」命令,因爲它需要永遠運行。也許「向量化」不是正確的工作,我的意思是類似於我們對numpy數組所做的事情,其中​​有對一次操作所有元素的命令,而不是使用命令「for」在每個元素中操作。

回答

1

恐怕你需要一個在任何情況下循環,但它並不慢。 Networkx實際上很慢,因爲它存儲節點和邊緣的方式(如字典)。如果您想使用numpy將函數應用於某些屬性,建議您嘗試使用graph-tool

至於手頭的問題,我想我有一個更好的辦法:

import networkx as nx 
import numpy as np 
from collections import Counter 

# This will yield weighted edges on the fly, no storage cost occurring 
def gen_edges(counter): 
    for k, v in counter.iteritems(): # change to counter.items() for Py3k+ 
     yield k[0], k[1], v 

g = nx.Graph() 
# Your edge list needs to be in the form of tuples 
# this map loop doesn't count 
connections = map(tuple, [[1,2],[2,3],[1,2],[2,1],[1,4],[2,3]]) 

# Create histogram of pairs using native Python collections 
c = Counter(connections) 
# Add weighted edges 
g.add_weighted_edges_from(gen_edges(c)) 

print nx.info(g) 
print g.edges(data=True) 

輸出:你不能使用numpy.unique算邊緣的直方圖

Name: 
Type: Graph 
Number of nodes: 4 
Number of edges: 3 
Average degree: 1.5000 

[(1, 2, {'weight': 1}), (1, 4, {'weight': 1}), (2, 3, {'weight': 2})] 

注意,因爲它展平陣列。

相關問題