web-dev-qa-db-fra.com

Tableau aléatoire binaire avec une proportion spécifique de ceux?

Quelle est la manière efficace (probablement vectorisée avec la terminologie Matlab) de générer un nombre aléatoire de zéros et de zéros avec une proportion spécifique? Spécialement avec Numpy?

Comme mon cas est spécial pour 1/3, mon code est:

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

Mais existe-t-il une fonction intégrée qui pourrait gérer cela plus efficacement au moins pour la situation de K/N où K et N sont des nombres naturels?

36
Cupitor

Encore une autre approche, en utilisant 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])
52
Jaime

Une méthode simple consiste à générer d’abord une ndarray avec la proportion de zéros et celle que vous voulez:

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

Ensuite, vous pouvez juste shuffle le tableau, rendant la distribution aléatoire:

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

Notez que cette approche vous donnera la proportion exacte de zéros/ceux que vous demandez, contrairement à l’approche binomiale. Si vous n’avez pas besoin de la proportion exacte, l’approche binomiale fonctionnera parfaitement.

18
mdml

Vous pouvez utiliser numpy.random.binomial. Par exemple. supposons que frac est la proportion de ceux-ci:

In [50]: frac = 0.15

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

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

Si je comprends bien votre problème, vous obtiendrez peut-être de l'aide avec 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

Simple one-liner: vous pouvez éviter d’utiliser des listes d’entiers et de distributions de probabilités, ce qui est peu intuitif et excessif pour ce problème à mon avis, en travaillant tout d’abord avec bools, puis en passant à int si nécessaire (en le laissant comme un tableau bool travailler dans la plupart des cas).

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