Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Random number generator with mean and Standard Deviation

Tags:

python

I need to know how to generate 1000 random numbers between 500 and 600 that has a mean = 550 and standard deviation = 30 in python.

import pylab
import random

xrandn = pylab.zeros(1000,float)

for j in range(500,601):
xrandn[j] = pylab.randn()

???????
like image 836
Mermeht2 Avatar asked Jan 08 '15 02:01

Mermeht2


3 Answers

You are looking for stats.truncnorm:

import scipy.stats as stats

a, b = 500, 600
mu, sigma = 550, 30
dist = stats.truncnorm((a - mu) / sigma, (b - mu) / sigma, loc=mu, scale=sigma)

values = dist.rvs(1000)
like image 51
elyase Avatar answered Oct 26 '22 10:10

elyase


I'm not exactly sure what the OP desired, but if he just wanted an array xrandn fulfilling the bottom plot - below I present the steps: enter image description here

First, create a standard distribution (Gaussian distribution), the easiest way might be to use numpy:

import numpy as np
random_nums = np.random.normal(loc=550, scale=30, size=1000)

And then you keep only the numbers within the desired range with a list comprehension:

random_nums_filtered = [i for i in random_nums if i>500 and i<600]
like image 27
NeStack Avatar answered Oct 26 '22 09:10

NeStack


There are other choices for your problem too. Wikipedia has a list of continuous distributions with bounded intervals, depending on the distribution you may be able to get your required characteristics with the right parameters. For example, if you want something like "a bounded Gaussian bell" (not truncated) you can pick the (scaled) beta distribution:

import numpy as np
import scipy.stats
import matplotlib.pyplot as plt

def my_distribution(min_val, max_val, mean, std):
    scale = max_val - min_val
    location = min_val
    # Mean and standard deviation of the unscaled beta distribution
    unscaled_mean = (mean - min_val) / scale
    unscaled_var = (std / scale) ** 2
    # Computation of alpha and beta can be derived from mean and variance formulas
    t = unscaled_mean / (1 - unscaled_mean)
    beta = ((t / unscaled_var) - (t * t) - (2 * t) - 1) / ((t * t * t) + (3 * t * t) + (3 * t) + 1)
    alpha = beta * t
    # Not all parameters may produce a valid distribution
    if alpha <= 0 or beta <= 0:
        raise ValueError('Cannot create distribution for the given parameters.')
    # Make scaled beta distribution with computed parameters
    return scipy.stats.beta(alpha, beta, scale=scale, loc=location)

np.random.seed(100)

min_val = 1.5
max_val = 35
mean = 9.87
std = 3.1
my_dist = my_distribution(min_val, max_val, mean, std)
# Plot distribution PDF
x = np.linspace(min_val, max_val, 100)
plt.plot(x, my_dist.pdf(x))
# Stats
print('mean:', my_dist.mean(), 'std:', my_dist.std())
# Get a large sample to check bounds
sample = my_dist.rvs(size=100000)
print('min:', sample.min(), 'max:', sample.max())

Output:

mean: 9.87 std: 3.100000000000001
min: 1.9290674232087306 max: 25.03903889816994

Probability density function plot:

Probability density function

Note that not every possible combination of bounds, mean and standard deviation will produce a valid distribution in this case, though, and depending on the resulting values of alpha and beta the probability density function may look like an "inverted bell" instead (even though mean and standard deviation would still be correct).

like image 34
jdehesa Avatar answered Oct 26 '22 09:10

jdehesa