使用SciPy或NumPy生成具有指定权重的离散随机variables

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

例如:

>>> 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是我应该使用的,请给我一个简单的例子和​​上面的“形状”的说明解释?

从一个分散的分布绘制直接内置于numpy。 该函数被称为random.choice (很难find没有任何参考在numpy文档离散分布)。

 elements = [1.1, 2.2, 3.3] probabilities = [0.2, 0.5, 0.3] np.random.choice(elements, 10, p=probabilities) 

这是一个简短的,相对简单的函数,返回加权值,它使用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我们创build箱。
  2. 然后我们使用random_sample创build一堆随机数(在01之间)
  3. 我们使用digitize来查看这些数字落入哪个分箱。
  4. 并返回相应的值。

你正朝着一个好的方向前进:内置的scipy.stats.rv_discrete()直接创build一个离散的随机variables。 下面是它的工作原理:

 >>> 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]) 

其中(整数)input值直接以期望的概率返回。

你也可以使用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) 

Etvoilà!

最简单的DIY方法是将概率归结为累积分布。 这样,您将单位间隔分成长度等于您的原始概率的子区间。 现在在[0,1)上生成一个单一的随机数均匀值,并且看它到达了哪个间隔。