矢量化numpy.random.multinomial

时间:2016-04-30 08:02:14

标签: python numpy vectorization random-sample

我正在尝试对以下代码进行矢量化:

for i in xrange(s.shape[0]):
            a[i] = np.argmax(np.random.multinomial(1,s[i,:]))

s.shape = 400 x 100 [给]。

a.shape = 400 [预计]。

是一个2D矩阵,它包含对的概率。 多项式应该从s矩阵的每一行中抽取一个随机样本,并将结果存储在向量a中。

2 个答案:

答案 0 :(得分:1)

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或定义vectorized的自定义版本适用于s结构:

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)

答案 1 :(得分:-2)

怎么样

[np.argmax(np.random.multinomial(1,s[i,:])) for i in xrange(s.shape[0])]