variable sacar numero metodos listas letras instalar generar funciones datos como aleatorios aleatorio aleatorias aleatoria python arrays random numpy random-sample

python - sacar - Matriz aleatoria binaria con una proporción específica de unos?



random letras python (5)

¿Cuál es la forma eficiente (probablemente vectorizada con la terminología de Matlab) de generar un número aleatorio de ceros y unos con una proporción específica? Especialmente con Numpy?

Como mi caso es especial para 1/3 , mi código es:

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

Pero, ¿hay alguna función incorporada que pueda manejar esto de manera más eficiente, al menos para la situación de K/N donde K y N son números naturales?


Otro enfoque más, usando 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])


Puedes usar numpy.random.binomial . Por ejemplo, supongamos que frac es la proporción de unos:

In [50]: frac = 0.15 In [51]: sample = np.random.binomial(1, frac, size=10000) In [52]: sample.sum() Out[52]: 1567


Si entiendo tu problema correctamente, podrías obtener ayuda con 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.])


Simple one-liner: puede evitar el uso de listas de enteros y distribuciones de probabilidad, que son poco intuitivas y excesivas para este problema en mi opinión, simplemente trabajando con bool s primero y luego lanzando a int si es necesario (aunque dejándolo como un bool array debería funcionar en la mayoría de los casos).

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


Una forma simple de hacer esto sería generar primero un ndarray con la proporción de ceros y unos que desee:

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

Luego puedes simplemente shuffle la matriz, haciendo que la distribución sea aleatoria:

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

Tenga en cuenta que este enfoque le dará la proporción exacta de ceros / unos que solicite, a diferencia del enfoque binomial. Si no necesita la proporción exacta, entonces el enfoque binomial funcionará bien.