【发布时间】:2016-03-15 05:12:51
【问题描述】:
numpy.random.choice 允许从向量中进行加权选择,即
arr = numpy.array([1, 2, 3])
weights = numpy.array([0.2, 0.5, 0.3])
choice = numpy.random.choice(arr, p=weights)
以概率 0.2 选择 1,以概率 0.5 选择 2,以概率 0.3 选择 3。
如果我们想以向量化的方式快速为每行都是概率向量的二维数组(矩阵)执行此操作怎么办?也就是说,我们想要一个随机矩阵中的选择向量?这是超级慢的方式:
import numpy as np
m = 10
n = 100 # Or some very large number
items = np.arange(m)
prob_weights = np.random.rand(m, n)
prob_matrix = prob_weights / prob_weights.sum(axis=0, keepdims=True)
choices = np.zeros((n,))
# This is slow, because of the loop in Python
for i in range(n):
choices[i] = np.random.choice(items, p=prob_matrix[:,i])
print(choices):
array([ 4., 7., 8., 1., 0., 4., 3., 7., 1., 5., 7., 5., 3.,
1., 9., 1., 1., 5., 9., 8., 2., 3., 2., 6., 4., 3.,
8., 4., 1., 1., 4., 0., 1., 8., 5., 3., 9., 9., 6.,
5., 4., 8., 4., 2., 4., 0., 3., 1., 2., 5., 9., 3.,
9., 9., 7., 9., 3., 9., 4., 8., 8., 7., 6., 4., 6.,
7., 9., 5., 0., 6., 1., 3., 3., 2., 4., 7., 0., 6.,
3., 5., 8., 0., 8., 3., 4., 5., 2., 2., 1., 1., 9.,
9., 4., 3., 3., 2., 8., 0., 6., 1.])
This post 建议 cumsum 和 bisect 可能是一种潜在的方法,而且速度很快。但是,虽然 numpy.cumsum(arr, axis=1) 可以沿着 numpy 数组的一个轴执行此操作,但 bisect.bisect 函数一次只能在一个数组上工作。同样,numpy.searchsorted 也仅适用于一维数组。
有没有一种仅使用矢量化操作的快速方法?
【问题讨论】:
标签: python numpy matrix vectorization random-sample