我必须定义一个网络,其中每条边的权重必须等于每对节点之间的连接数。以下代码生成这样的网络:
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
类的map
或imap
方法。
https://docs.python.org/2/library/multiprocessing.html
然后,您可以创建一个检查并添加边的函数,并获得imap
来并行执行每个元素的函数。
查看此链接底部的示例:
https://docs.python.org/2/library/multiprocessing.html#module-多访问.pool