9

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?

4
  • Related: stackoverflow.com/q/61352259/270986 Commented Oct 1, 2020 at 17:28
  • @olenscki Just saw your comment about consecutive figures with the same number. Are you sure you need multiple frames? Maybe \begin{frame} \begin{figure} \includegraphics<1>{example-image-a} \includegraphics<2>{example-image-b} \caption{text} \end{figure} \end{frame} would be easier? Commented Oct 3, 2020 at 21:28
  • @samcarter_is_at_topanswers.xyz i was trying to show the same picture and change the text below. This one you suggested would perhaps be easier if I had 2 images and one text, no?
    – olenscki
    Commented Oct 3, 2020 at 22:01
  • @olenscki To change the text, maybe \only<1>{text first slide}\only<2>{text second slide} is easier? (manipulating the counter to decrease the figure number is a bit risky because you'll break cross references) Commented Oct 4, 2020 at 11:27

1 Answer 1

9

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])
3
  • Thank you for your response! I've one last question: why did they do this?
    – olenscki
    Commented Oct 1, 2020 at 17:41
  • I think NEP 19 explains it fairly well. The legacy system made some promises about reproducibility, and those promises turned out to seriously constrain further development and improvements. So at that point if you want to continue development on the random system you have two choices: break the promises, or create a new system to replace the old (but keep the old one around to avoid breaking existing code). And the creation of a new system provided some opportunities to do some other nice things, like allow different core bit generators. Commented Oct 1, 2020 at 18:40
  • Making fundamental changes to existing code is tricky. It's easy to break something. It's easier to develop a new package from ground up, and test it among 'friends' (as its own github project), and then when stable, port it to a main stream package.
    – hpaulj
    Commented Oct 1, 2020 at 19:39

Not the answer you're looking for? Browse other questions tagged or ask your own question.