在networkx中,如何以矢量化方式更新边缘权重?

时间:2016-05-05 01:34:10

标签: python 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”,因为它需要永远运行。也许“vectorize”不是正确的工作,我的意思是类似于我们对numpy数组所做的事情,其中​​有一些命令可以同时对所有元素进行操作,而不是使用命令“for”来操作每个元素。

2 个答案:

答案 0 :(得分:1)

我担心在任何情况下你都需要一个for循环,但它并不那么慢。 Networkx实际上通常很慢,因为它存储节点和边缘(如dict)。如果你想使用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)

输出:

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})]

请注意,您不能使用numpy.unique计算边的直方图,因为它会使数组变平。

答案 1 :(得分:0)

尝试使用map库的imap类的Poolmultiprocessing方法。

https://docs.python.org/2/library/multiprocessing.html

然后,您可以创建一个检查并添加边的函数,并获得imap以并行执行每个元素的函数。

检查此链接底部的示例:

https://docs.python.org/2/library/multiprocessing.html#module-multiprocessing.pool