55

我正在寻找一个简单的函数,它可以根据它们对应的(也指定的)概率生成指定随机值的数组。我只需要它来生成浮点值,但我不明白为什么它不能生成任何标量。我可以想出许多从现有函数构建它的方法,但我想我可能只是错过了一个明显的 SciPy 或 NumPy 函数。

例如:

>>> values = [1.1, 2.2, 3.3]
>>> probabilities = [0.2, 0.5, 0.3]
>>> print some_function(values, probabilities, size=10)
(2.2, 1.1, 3.3, 3.3, 2.2, 2.2, 1.1, 2.2, 3.3, 2.2)

注意:我找到了 scipy.stats.rv_discrete但我不明白它是如何工作的。具体来说,我不明白这(下)是什么意思,也不应该做什么:

numargs = generic.numargs
[ <shape(s)> ] = ['Replace with resonable value', ]*numargs

如果 rv_discrete 是我应该使用的,您能否为我提供一个简单的示例和对上述“形状”语句的解释?

4

5 回答 5

76

从离散分布中绘图直接内置到 numpy. 该函数称为random.choice(如果不参考 numpy 文档中的离散分布,很难找到)。

elements = [1.1, 2.2, 3.3]
probabilities = [0.2, 0.5, 0.3]
np.random.choice(elements, 10, p=probabilities)
于 2015-08-24T10:11:12.980 回答
25

这是一个简短的、相对简单的函数,它返回加权值,它使用 NumPy 的digitizeaccumulaterandom_sample

import numpy as np
from numpy.random import random_sample

def weighted_values(values, probabilities, size):
    bins = np.add.accumulate(probabilities)
    return values[np.digitize(random_sample(size), bins)]

values = np.array([1.1, 2.2, 3.3])
probabilities = np.array([0.2, 0.5, 0.3])

print weighted_values(values, probabilities, 10)
#Sample output:
[ 2.2  2.2  1.1  2.2  2.2  3.3  3.3  2.2  3.3  3.3]

它是这样工作的:

  1. 首先使用accumulate我们创建垃圾箱。
  2. 然后我们使用创建一堆随机数(介于0和之间1random_sample
  3. 我们digitize用来查看这些数字属于哪些垃圾箱。
  4. 并返回相应的值。
于 2012-07-07T09:42:44.593 回答
15

您正朝着一个好的方向前进:内置scipy.stats.rv_discrete()非常直接地创建了一个离散随机变量。下面是它的工作原理:

>>> from scipy.stats import rv_discrete  

>>> values = numpy.array([1.1, 2.2, 3.3])
>>> probabilities = [0.2, 0.5, 0.3]

>>> distrib = rv_discrete(values=(range(len(values)), probabilities))  # This defines a Scipy probability distribution

>>> distrib.rvs(size=10)  # 10 samples from range(len(values))
array([1, 2, 0, 2, 2, 0, 2, 1, 0, 2])

>>> values[_]  # Conversion to specific discrete values (the fact that values is a NumPy array is used for the indexing)
[2.2, 3.3, 1.1, 3.3, 3.3, 1.1, 3.3, 2.2, 1.1, 3.3]

因此,上面的分布从列表中distrib返回索引。values

更一般地说,在其参数的第一个元素中rv_discrete()采用一系列values=(…,…)数值,并在这种情况下返回这些值;无需转换为特定的(浮点)值。这是一个例子:

>>> values = [10, 20, 30]
>>> probabilities = [0.2, 0.5, 0.3]
>>> distrib = rv_discrete(values=(values, probabilities))
>>> distrib.rvs(size=10)
array([20, 20, 20, 20, 20, 20, 20, 30, 20, 20])

其中(整数)输入值以所需概率直接返回。

于 2013-02-02T08:11:25.260 回答
5

最简单的 DIY 方法是将概率总结为累积分布。这样,您将单位间隔拆分为长度等于原始概率的子间隔。现在在 [0,1) 上生成一个统一的随机数,并查看它落在哪个区间。

于 2012-07-07T12:06:25.993 回答
4

您还可以使用Lea,这是一个专门用于离散概率分布的纯 Python 包。

>>> distrib = Lea.fromValFreqs((1.1,2),(2.2,5),(3.3,3))
>>> distrib
1.1 : 2/10
2.2 : 5/10
3.3 : 3/10
>>> distrib.random(10)
(2.2, 2.2, 1.1, 2.2, 2.2, 2.2, 1.1, 3.3, 1.1, 3.3)

瞧!

于 2013-12-13T11:59:56.440 回答