在comments 中,据说有人尝试对这个here 进行矢量化,但是,这不仅仅是 一种尝试。这个问题也是一个完整的解决方案。
问题的目标是获得包含多项事件的1的位置的索引。也就是说,下面的实现[0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0]会产生14。因此,它实际上等价于执行:
np.random_choice(np.arange(len(p)),p=p) # here, p is s[i,:]
因此,Warren Weckesser solution 到 在随机矩阵的所有行中进行快速随机加权选择 也是该问题的解决方案。唯一的区别是概率向量是按行还是按列定义的,这可以很容易地解决,要么将s 转置为prob_matrix,要么定义适用于s 结构的vectorized 的自定义版本:
def vectorized(prob_matrix, items):
s = prob_matrix.cumsum(axis=1)
r = np.random.rand(prob_matrix.shape[0])
k = (s < r).sum(axis=1)
return items[k]
在这个问题中,尺寸为 400x400,加速大约是 10 倍:
%%timeit
a = np.empty(400)
for i in range(s.shape[0]):
a[i] = np.argmax(np.random.multinomial(1,s[i,:]))
# 5.96 ms ± 46.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
vals = np.arange(400,dtype=int)
vectorized(s,vals)
# 544 µs ± 5.49 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)