[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

random.gauss: range

Gustavo DiPietro

2/26/2010 9:27:00 PM

hi,
i'm trying the random.gauss function. can anyone explain how to get a
number between a given range? like, from 0 to 20 with an average of
10? and how to determine the "steep" of the curve? i've never studied
it, so mu and sigma don't really tell me a thing.

thanks in advange
5 Answers

Robert Kern

2/26/2010 9:57:00 PM

0

On 2010-02-26 15:26 PM, pistacchio wrote:
> hi,
> i'm trying the random.gauss function. can anyone explain how to get a
> number between a given range?

You don't. The Gaussian distribution has infinite range. The best you can do
with the standard library is to keep sampling until you get a number inside your
desired range. If you aren't careful about your choice of parameters, this could
waste a lot of time.

> like, from 0 to 20 with an average of
> 10? and how to determine the "steep" of the curve? i've never studied
> it, so mu and sigma don't really tell me a thing.

Study it:

http://en.wikipedia.org/wiki/Normal_di...

mu is the mean, the location of the central peak. sigma is the standard
deviation, which controls the width of the peak. Larger sigma means wider and
shorter peak.

You may want another distribution, like random.betavariate():

http://en.wikipedia.org/wiki/Beta_di...

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

Gustavo DiPietro

2/27/2010 12:46:00 AM

0

thanks, betadistribute did the work... and i learned a new thing!

On 26 Feb, 22:56, Robert Kern <robert.k...gmail.com> wrote:
> On 2010-02-26 15:26 PM, pistacchio wrote:
>
> > hi,
> > i'm trying the random.gauss function. can anyone explain how to get a
> > number between a given range?
>
> You don't. The Gaussian distribution has infinite range. The best you can do
> with the standard library is to keep sampling until you get a number inside your
> desired range. If you aren't careful about your choice of parameters, this could
> waste a lot of time.
>
> > like, from 0 to 20 with an average of
> > 10? and how to determine the "steep" of the curve? i've never studied
> > it, so mu and sigma don't really tell me a thing.
>
> Study it:
>
>    http://en.wikipedia.org/wiki/Normal_di...
>
> mu is the mean, the location of the central peak. sigma is the standard
> deviation, which controls the width of the peak. Larger sigma means wider and
> shorter peak.
>
> You may want another distribution, like random.betavariate():
>
>    http://en.wikipedia.org/wiki/Beta_di...
>
> --
> Robert Kern
>
> "I have come to believe that the whole world is an enigma, a harmless enigma
>   that is made terrible by our own mad attempt to interpret it as though it had
>   an underlying truth."
>    -- Umberto Eco

Raymond Hettinger

2/27/2010 12:46:00 AM

0

On Feb 26, 1:26 pm, pistacchio <pistacc...@gmail.com> wrote:
> hi,
> i'm trying the random.gauss function. can anyone explain how to get a
> number between a given range? like, from 0 to 20 with an average of
> 10? and how to determine the "steep" of the curve? i've never studied
> it, so mu and sigma don't really tell me a thing.

Try random.randrange() and random.triangular().
They are both easy to use and do not require you
to enter parameters that you don't understand.

FWIW, mu and sigma refer to the average and standard deviation
of a normal distribution.


Raymond

Steven D'Aprano

2/27/2010 2:53:00 AM

0

On Fri, 26 Feb 2010 13:26:44 -0800, pistacchio wrote:

> hi,
> i'm trying the random.gauss function. can anyone explain how to get a
> number between a given range? like, from 0 to 20 with an average of 10?

That's not what a Gaussian distribution does. It has an infinite range.
Are you sure you want a Gaussian, and not a uniform distribution or a
triangular distribution?

You could pin the values to the appropriate range:

def pinned_gaussian(a, b, mu, sigma):
"""Return a Gaussian random number pinned to [a, b]."""
return min(b, max(a, random.gauss(mu, sigma)))

but that will distort the randomness slightly: you will have a slight
excess of values equal to a and b than you otherwise might expect. You
might not care, though, particularly if the sigma is very small relative
to the minimum and maximum you want.

Alternatively, you could use this approach:

def truncated_gauss(a, b, mu, sigma):
"""Return a random number from a truncated Gaussian distribution."""
while 1:
x = random.gauss(mu, sigma)
if a <= x <= b:
return x



> and how to determine the "steep" of the curve? i've never studied it, so
> mu and sigma don't really tell me a thing.

mu is the average -- in your example above, mu would be 10.

sigma is the standard deviation of the random variable. It tells you how
much the random variable actually varies: if sigma is close to zero, most
of the numbers will be close to mu and the graph will look like a spike;
if sigma is large, it will be very broad and flat.

Statistically, the following rules apply:

68% of the numbers will be between (mu - sigma) and (mu + sigma).
95% of the numbers will be between (mu - 2*sigma) and (mu + 2*sigma).
99.7% of the numbers will be between (mu - 3*sigma) and (mu + 3*sigma).

(the percentages are approximate, not exact). So you could get a
reasonable approximation to a normal distribution truncated between 0 and
20 with:

truncated_gauss(0, 20, 10, 10.0/3)




--
Steven

Gregory Ewing

2/28/2010 4:27:00 AM

0

Steven D'Aprano wrote:
> def pinned_gaussian(a, b, mu, sigma):
> """Return a Gaussian random number pinned to [a, b]."""
> return min(b, max(a, random.gauss(mu, sigma)))
>
> def truncated_gauss(a, b, mu, sigma):
> """Return a random number from a truncated Gaussian distribution."""
> while 1:
> x = random.gauss(mu, sigma)
> if a <= x <= b:
> return x

If it doesn't have to be strictly gaussian, another way is to
approximate it by adding some number of uniformly distributed
samples together. If you have n uniform samples ranging from
0 to a, the sum will be in the range 0 to n*a and the mean
will be n*a/2. The greater the value of n, the closer the
distribution will be to normal.

--
Greg