55

対応する(指定された)確率に基づいて指定されたランダム値の配列を生成できる単純な関数を探しています。float値を生成するためだけに必要ですが、スカラーを生成できない理由がわかりません。既存の関数からこれを構築する多くの方法を考えることができますが、おそらく明らかな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を使用する必要がある場合は、簡単な例と上記の「shape」ステートメントの説明を教えてください。

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の、、、およびを使用digitizeaccumulateますrandom_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次に、を使用して(との間の1)乱数の束を作成します。random_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

離散確率分布専用の純粋なPythonパッケージであるLeaを使用することもできます。

>>> 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à!

于 2013-12-13T11:59:56.440 に答える