在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数组所做的事情,在numpy数组中,有命令可以同时对所有元素进行操作,而不是使用命令"for"对每个元素进行操作。

恐怕无论如何都需要一个for循环,但它并没有那么慢。Networkx实际上通常相当慢,因为它存储节点和边的方式(如dict)。如果您想使用numpy将函数应用于某些属性,我建议您尝试图形工具。

关于眼前的问题,我想我有一个更好的方法:

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来计算边的直方图,因为它会使数组变平。

尝试使用multiprocessing库的Pool类的mapimap方法。

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

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

查看此链接底部的示例:

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

最新更新