web-dev-qa-db-ja.com

1の特定の割合を持つバイナリランダム配列?

特定の割合でゼロと1の乱数を生成する効率的な(おそらくMatlab用語でベクトル化された)方法は何ですか?特にNumpyとは?

私の場合は1/3に特別なものなので、私のコードは次のとおりです。

import numpy as np 
a=np.mod(np.multiply(np.random.randomintegers(0,2,size)),3)

しかし、少なくともKとNが自然数であるK/Nの状況で、これをより効率的に処理できる組み込み関数はありますか?

47
Cupitor

np.random.choice を使用したさらに別のアプローチ:

>>> np.random.choice([0, 1], size=(10,), p=[1./3, 2./3])
array([0, 1, 1, 1, 1, 0, 0, 0, 0, 0])
61
Jaime

これを行う簡単な方法は、最初に0と1の割合でndarrayを生成することです:

>>> import numpy as np
>>> N = 100
>>> K = 30 # K zeros, N-K ones
>>> arr = np.array([0] * K + [1] * (N-K))
>>> arr
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1])

次に、配列をshuffleするだけで、分布をランダムにできます。

>>> np.random.shuffle(arr)
>>> arr
array([1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0,
       1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1,
       1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
       0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1,
       1, 1, 1, 0, 1, 1, 1, 1])

このアプローチは、二項アプローチとは異なり、要求するゼロ/ワンの正確な比率を提供することに注意してください。正確な比率を必要としない場合、二項アプローチはうまく機能します。

20
mdml

numpy.random.binomialを使用できます。例えば。 fracが1の割合であるとします:

In [50]: frac = 0.15

In [51]: sample = np.random.binomial(1, frac, size=10000)

In [52]: sample.sum()
Out[52]: 1567
15

あなたの問題を正しく理解していれば、 numpy.random.shuffle で助けが得られるかもしれません

>>> def Rand_bin_array(K, N):
    arr = np.zeros(N)
    arr[:K]  = 1
    np.random.shuffle(arr)
    return arr

>>> Rand_bin_array(5,15)
array([ 0.,  1.,  0.,  1.,  1.,  1.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,
        0.,  0.])
4
Abhijit

シンプルなワンライナー:boolsを最初に処理してからint if必要です(ただし、ほとんどの場合、bool配列のままにしておく必要があります)。

>>> import numpy as np
>>> np.random.random(9) < 1/3.
array([False,  True,  True,  True,  True, False, False, False, False])   
>>> (np.random.random(9) < 1/3.).astype(int)
array([0, 0, 0, 0, 0, 1, 0, 0, 1])    
0

1と0の正確な数を取得する別の方法は、np.random.choiceを使用して置換なしでインデックスをサンプリングすることです。

arr_len = 30
num_ones = 8

arr = np.zeros(arr_len, dtype=int)
idx = np.random.choice(range(arr_len), num_ones, replace=False)
arr[idx] = 1

でる:

arr

array([0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1,
       0, 0, 0, 0, 0, 1, 0, 0])
0
joelostblom