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