简体   繁体   中英

How to make a mixed random variable in scipy.stats

I am trying to understand the random variables from scipy.stats. I can sample from a uniform random variable:

from scipy.stats import uniform
print(uniform.rvs(size=1000))

But how can I make a random variable that with 0.5 probability samples uniformly from 0..1 and with 0.5 prob samples uniformly from 5..6 ?

I could write a loop that picks a random number between 0 and 1. If it is < .5, then picks a random number between 0 and 1. If it is >= .5 pick a random number between 0 and 1 and add 5. But I would really like to be able to call it like:

mixed_uniform.rvs(size=1000)

I also need to use the survival function of this mixed distribution.

For the distribution, a mix of a custom function to do the transformation, then use vectorize() to apply it will be more efficient than looping.

In [1]: from scipy.stats import uniform

In [2]: r = uniform.rvs(size=1000)

In [3]: r
Out[3]:
array([7.48816182e-02, 4.63880797e-01, 8.75315477e-01, 3.61116729e-01,
       ...
       3.13473322e-01, 3.45434625e-01, 9.49993090e-01, 1.55553018e-01])

In [4]: type(r)
Out[4]: numpy.ndarray

In [8]: def f(a):
   ...:     a *= 2
   ...:     if a > 1: a += 4
   ...:     return a
   ...:


In [10]: import numpy

In [11]: vf = numpy.vectorize(f)

In [12]: r2 = numpy.vectorize(f)(r)

In [13]: r2
Out[13]:
array([1.49763236e-01, 9.27761594e-01, 5.75063095e+00, 7.22233457e-01,
       ...
       6.26946644e-01, 6.90869250e-01, 5.89998618e+00, 3.11106036e-01])

In [14]: max(r2)
Out[14]: 5.999360665646841

In [15]: min(r2)
Out[15]: 0.0004563758727054168

In [17]: len([x for x in r2 if x<=2])
Out[17]: 504

In [18]: len([x for x in r2 if x>=5])
Out[18]: 496

I generate a random distribution of 1000 numbers between 0 and 1 and randomly chose a element from the list. if the element is greater than .5 then add 5

from scipy.stats import uniform
import random
min_number=0
max_number=1
size=1000

number_pool= uniform.rvs(min_number,max_number,size=size)

plt.hist(number_pool)
plt.show()

def getValue(number_pool):
    val=random.choice(number_pool)
    if val>.5: 
        val+=5
    return val
print(getValue(number_pool))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM