numpy一次绘制一些bernoulli分布

时间:2016-04-04 09:03:46

标签: python numpy random

说我想立刻从伯努利分布列表中抽取,例如概率为[0.1, 0.2, 0.3]。我可以用for循环来做这个但是有一个更好的numpy方式(使用scipy也没关系)?

ps = [0.1, 0.2, 0.3]
[np.random.choice(2, p=[1 - p, p]) for p in ps]

2 个答案:

答案 0 :(得分:4)

您可以从二项式中绘制n=1,这相当于伯努利。由于二项式接受数组作为概率参数,因此您可以使用:

np.random.binomial(1, p=ps)

您可以通过向某些元素提供非常小/大的概率来测试它是否正常工作,并多次调用该函数。

例如,让ps = [0.23, 0.48, 0.64, 0.98]

In [90]: np.sum([np.random.binomial(1,p=ps) for i in range(100000)], axis=0)
Out[90]: array([23000, 48115, 64128, 97957])

答案 1 :(得分:0)

我建议宁愿使用(np.random.uniform(size=d) < probs) * 1,其中probs是您的概率向量。这样会生成统一的随机变量,然后将其阈值设置为01,得到1的概率正是您在probs中拥有的概率。

如果您只需要几个bernoulli变量,并且只需一次使用np.random.binomial的解决方案就可以了。但是,这似乎比使用均匀分布生成bernoulli变量要慢几倍。例如,如果我们有一些概率随机向量 probs = np.uniform(size=10000), 然后我们得到

%timeit np.random.binomial(n=1, p=probs, size=10000)
Result: 775 µs ± 5.35 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit (np.random.uniform(size=10000) < probs) * 1
Result: 103 µs ± 510 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)