【发布时间】:2018-03-28 12:31:36
【问题描述】:
我用 python 和 numpy 做了一个随机游走生成器。给定一个邻接矩阵,我想从每个节点中抽取随机路径。为此,我目前制作了这个类,它将图中每个节点的邻居节点及其相应的概率作为输入:
import numpy as np
class RandomChoice(object):
def __init__(self, neighbors_choices, neighbors_prob, depth=50):
C = len(neighbors_choices)
self.depth = depth
self.neighbors_choices = neighbors_choices
self.neighbors_prob = neighbors_prob
self.index = np.zeros(C, np.uint32)
self.choices = list()
for i in range(C):
self.choices.append(np.random.choice(self.neighbors_choices[i], size=self.depth, p=self.neighbors_prob[i]))
def __getitem__(self, arg):
if self.index[arg] == self.depth:
self.choices[arg] = np.random.choice(self.neighbors_choices[arg], size=self.depth, p=self.neighbors_prob[arg])
self.index[arg] = 0
val = self.choices[arg][self.index[arg]]
self.index[arg] += 1
return val
我是这样使用它的:
# Example with a 3x3 matrix
# 1 2 1
# 3 0 1
# 0 1 0
number_of_walks_per_node = 5
number_of_nodes = 3
length_of_walks = 10
choices = [
[0, 1, 2],
[0, 2],
[1]
]
probs = [
[0.25, 0.5, 0.25],
[0.75, 0.25],
[1]
]
randomChoice = RandomChoice(choices, probs, depth=50)
for i in range(number_of_walks_per_node):
for starting_node in range(number_of_nodes):
walker_positions = [starting_node]
for j in range(length_of_walks):
walker_positions.append( randomChoice[walker_positions[j]])
print(walker_positions)
这里的想法是利用 numpy.random.choices 对 RAM 中的一些空间的向量效率。但是这个功能仍然是这段代码的瓶颈。我认为 numpy.random.choices 花时间检查概率总和是否为 1,并且每个概率都大于 0。你知道如何加快这段代码的速度吗?
【问题讨论】:
-
I think numpy.random.choices spends time checking that the probabilities sum to 1 and that each one of them is greater than 0不只是从列表中选择一个随机元素吗?该列表不需要包含 pdf,因此我认为它不会进行任何检查。 -
我不知道这是否是最新的,但请查看:github.com/numpy/numpy/issues/4188
-
@debzsub 无法运行您的代码。请您上传一个遵循这些准则stackoverflow.com/help/mcve 的示例,以便更容易为您提供帮助。
-
对对对,我编辑一下
-
只看你所拥有的(暂时忽略 np.choice),我建议你使用队列 @987654323@ 或 dequeue docs.python.org/2/library/collections.html#collections.deque(你需要选择合适的) 而不是列表,如果您要进行许多追加,然后弹出结果,因为如果您只使用它们来串行存储数据并且您不关心对它们进行索引,它们会更快。
标签: python performance numpy random-walk