python - 为给定的二维概率数组沿轴向量化 `numpy.random.choice`

标签 python numpy random vectorization

Numpy 具有 random.choice 函数,可让您从分类分布中抽样。你会如何在一个轴上重复这个?为了说明我的意思,这是我当前的代码:

categorical_distributions = np.array([
    [.1, .3, .6],
    [.2, .4, .4],
])
_, n = categorical_distributions.shape
np.array([np.random.choice(n, p=row)
          for row in categorical_distributions])

理想情况下,我想消除 for 循环。

最佳答案

这是获取每行随机索引的一种矢量化方法,使用 a 作为 2D 概率数组 -

(a.cumsum(1) > np.random.rand(a.shape[0])[:,None]).argmax(1)

泛化以覆盖 2D 数组的行和列 -

def random_choice_prob_index(a, axis=1):
    r = np.expand_dims(np.random.rand(a.shape[1-axis]), axis=axis)
    return (a.cumsum(axis=axis) > r).argmax(axis=axis)

让我们通过运行超过一百万次来验证给定的样本 -

In [589]: a = np.array([
     ...:     [.1, .3, .6],
     ...:     [.2, .4, .4],
     ...: ])

In [590]: choices = [random_choice_prob_index(a)[0] for i in range(1000000)]

# This should be close to first row of given sample
In [591]: np.bincount(choices)/float(len(choices))
Out[591]: array([ 0.099781,  0.299436,  0.600783])

运行时测试

原始循环方式-

def loopy_app(categorical_distributions):
    m, n = categorical_distributions.shape
    out = np.empty(m, dtype=int)
    for i,row in enumerate(categorical_distributions):
        out[i] = np.random.choice(n, p=row)
    return out

更大阵列的时间 -

In [593]: a = np.array([
     ...:     [.1, .3, .6],
     ...:     [.2, .4, .4],
     ...: ])

In [594]: a_big = np.repeat(a,100000,axis=0)

In [595]: %timeit loopy_app(a_big)
1 loop, best of 3: 2.54 s per loop

In [596]: %timeit random_choice_prob_index(a_big)
100 loops, best of 3: 6.44 ms per loop

关于python - 为给定的二维概率数组沿轴向量化 `numpy.random.choice`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47722005/

相关文章:

python - 使用 pip 在 Python 3.3 上安装 ckanclient 时出错

python - 曲线和对角线之间的填充区域

c++ - 程序生成的伪随机

java - 我应该定期重新播种 SecureRandom 还是自动发生?

javascript - 生成随机种子十六进制颜色?

python - odoo 中继承模型的相关字段

python - 禁用 argparse 中类似参数的连接和缩写

python - Pandas/Python 根据另一列的字符串值列出一列的值

Numpy 矩阵乘法与自定义点积

python - 如何检查数组的所有值是否彼此相等?