Comprende el código de forma correcta antes de usarlo a tu proyecto y si tdeseas aportar algo puedes dejarlo en los comentarios.
Parece que quieres una distribución normal truncada. Usando scipy, podrías usar scipy.stats.truncnorm
para generar variaciones aleatorias a partir de tal distribución:
import matplotlib.pyplot as plt
import scipy.stats as stats
lower, upper = 3.5, 6
mu, sigma = 5, 0.7
X = stats.truncnorm(
(lower - mu) / sigma, (upper - mu) / sigma, loc=mu, scale=sigma)
N = stats.norm(loc=mu, scale=sigma)
fig, ax = plt.subplots(2, sharex=True)
ax[0].hist(X.rvs(10000), normed=True)
ax[1].hist(N.rvs(10000), normed=True)
plt.show()
La figura superior muestra la distribución normal truncada, la figura inferior muestra la distribución normal con la misma media mu
y desviación estándar sigma
.
Encontré esta publicación mientras buscaba una forma de devolver una serie de valores muestreados de una distribución normal truncada entre cero y 1 (es decir, probabilidades). Para ayudar a cualquier otra persona que tenga el mismo problema, solo quería señalar que scipy.stats.truncnorm tiene la capacidad integrada “.rvs”.
Entonces, si desea 100 000 muestras con una media de 0,5 y una desviación estándar de 0,1:
import scipy.stats
lower = 0
upper = 1
mu = 0.5
sigma = 0.1
N = 100000
samples = scipy.stats.truncnorm.rvs(
(lower-mu)/sigma,(upper-mu)/sigma,loc=mu,scale=sigma,size=N)
Esto da un comportamiento muy similar a numpy.random.normal, pero dentro de los límites deseados. Usar el integrado será sustancialmente más rápido que hacer un bucle para recopilar muestras, especialmente para valores grandes de N.
En caso de que alguien quiera una solución usando solo numpy, aquí hay una implementación simple usando una función normal y un clip (el enfoque de MacGyver):
import numpy as np
def truncated_normal(mean, stddev, minval, maxval):
return np.clip(np.random.normal(mean, stddev), minval, maxval)
EDITAR: ¡NO use esto! asi es como no se debe hacer!! por ejemplo,a = truncated_normal(np.zeros(10000), 1, -10, 10)
puede parecer que funciona, perob = truncated_normal(np.zeros(10000), 100, -1, 1)
será definitivamente no dibujar una normal truncadacomo se puede ver en el siguiente histograma:
Lo siento por eso, ¡espero que nadie haya resultado herido! Supongo que la lección es, no trates de emular a MacGyver en la codificación… Saludos,
Andrés
Tienes la opción de sostener nuestra labor dejando un comentario y puntuándolo te estamos eternamente agradecidos.