2016-05-05 26 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})] 

注意,因为它展平阵列。

相关问题