Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between numpy.random vs numpy.random.Generate

I've been trying to simulate some Monte Carlos simulations lately and came across numpy.random. Checking the documentation of the exponential generator I've noticed that that's a warning in the page, which tells that

Generator.exponential should be used for new code.

Althought that, numpy.random.exponential still works, but I couldn't run the Generator counterpart. I've been getting the following error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-c4cc7e61aa98> in <module>
----> 1 np.random.Generator.exponential(2, 1000)

TypeError: descriptor 'exponential' for 'numpy.random._generator.Generator' objects doesn't apply to a 'int' object

My questions are:

  1. What's the difference between these 2?

  2. How to generate a sample with Generator?

like image 778
olenscki Avatar asked Oct 01 '20 16:10

olenscki


1 Answers

The Generator referred to in the documentation is a class, introduced in NumPy 1.17: it's the core class responsible for adapting values from an underlying bit generator to generate samples from various distributions. numpy.random.exponential is part of the (now) legacy Mersenne-Twister-based random framework. You probably shouldn't worry about the legacy functions being removed any time soon - doing so would break a huge amount of code, but the NumPy developers recommend that for new code, you should use the new system, not the legacy system.

Your best source for the rationale for the change to the system is probably NEP 19: https://numpy.org/neps/nep-0019-rng-policy.html

To use Generator.exponential as recommended by the documentation, you first need to create an instance of the Generator class. The easiest way to create such an instance is to use the numpy.random.default_rng() function.

So you want to start with something like:

>>> import numpy
>>> my_generator = numpy.random.default_rng()

At this point, my_generator is an instance of numpy.random.Generator:

>>> type(my_generator)
<class 'numpy.random._generator.Generator'>

and you can use my_generator.exponential to get variates from an exponential distribution. Here we take 10 samples from an exponential distribution with scale parameter 3.2 (or equivalently, rate 0.3125):

>>> my_generator.exponential(3.2, size=10)
array([6.26251663, 1.59879107, 1.69010179, 4.17572623, 5.94945358,
       1.19466134, 3.93386506, 3.10576934, 1.26095418, 1.18096234])

Your Generator instance can of course also be used to get any other random variates you need:

>>> my_generator.integers(0, 100, size=3)
array([56, 57, 10])
like image 146
Mark Dickinson Avatar answered Nov 15 '22 03:11

Mark Dickinson