K
K
kAIST2016-01-05 01:10:09
Python
kAIST, 2016-01-05 01:10:09

How to make random with non-uniform distribution in Python?

There is a list from which you need to randomly select an element. But the probability that the element at the beginning of the list will fall out should be higher than at the end.
How to implement this in Python?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
R
Roman_Kh, 2016-01-05
@Roman_Kh

First, be very specific about what it means "at the beginning, the probability is higher than at the end."
Then you can write your distribution function. For example, your list has 4 elements and the probabilities are distributed as follows: 60, 25, 12, 3, that is, 60% for the 1st element, 25% for the 2nd and so on.
Then

your_data_list = [...]
probabilities_list=[60, 85, 97, 100]
rnd = random.uniform(1, 100)
idx = -1
idx_found = False
while idx < len(probabilities_list) and not idx_found:
  idx += 1
  idx_found = rnd <= probabilities_list[idx]
your_random = your_data_list[idx]

However, this is a very slow method (and not without some problems).
You can make it faster and shorter using the bisect module :
This option will be noticeably faster (sometimes by 20%, but sometimes by 3.5 times).
But it's best to use numpy :
It will be 10 times faster.
In this case, prb_list should contain exactly the probabilities of occurrence of each element, i.e. for the example above [0.6, 0.25, 0.12, 0.03]

N
nirvimel, 2016-01-05
@nirvimel

I made a reference table on the functions of the random module , which generate values ​​with a given probability distribution.

FunctionProbability distribution
random.uniform(a, b)Uniform distribution
( Continuous uniform distribution )
random.triangular(low, high, mode)triangular distribution
random.betavariate(alpha, beta)Beta distribution
( Beta distribution )
random.expovariate(lambd)Exponential distribution
( Exponential distribution )
random.gammavariate(alpha, beta)Gamma distribution
( Gamma distribution )
random.normalvariate(mu, sigma)
Normal distribution
( Normal distribution )
random.lognormvariate(mu, sigma)Log-normal distribution
( Lognormal distribution )
random.vonmisesvariate(mu, kappa)Von_Mises_distribution
random.paretovariate(alpha)Pareto distribution
( Pareto distribution )
random.weibullvariate(alpha, beta)Weibull distribution
( Weibull distribution )

As for the question, depending on the shape of the chart you're after, one of these might work for you:
  • random.expovariate(1.)(the lambd parameter characterizes the "slope" of the graph, the value 1. is chosen arbitrarily)
  • math.fabs(random.gauss(0., 1.))(the sigma parameter characterizes the "slope" of the graph, the value 1 is chosen arbitrarily)
  • Didn't find what you were looking for?

    Ask your question

    Ask a Question

    731 491 924 answers to any question