1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
.. _new-or-different:
.. currentmodule:: numpy.random
What's new or different
-----------------------
NumPy 1.17.0 introduced `Generator` as an improved replacement for
the :ref:`legacy <legacy>` `RandomState`. Here is a quick comparison of the two
implementations.
======================= ================== =============
Feature Older Equivalent Notes
----------------------- ------------------ -------------
`Generator` `RandomState` `Generator` requires a stream
source, called a `BitGenerator`
A number of these are provided.
`RandomState` uses the Mersenne
Twister `MT19937` by default,
but can also be instantiated
with any BitGenerator.
----------------------- ------------------ -------------
`~.Generator.random` `random_sample`, Access the values in a
`rand` BitGenerator, convert them to
``float64`` in the interval
``[0.0., 1.0)``. In addition
to the ``size`` kwarg, now
supports ``dtype='d'`` or
``dtype='f'``, and an ``out``
kwarg to fill a user-supplied
array.
Many other distributions are also
supported.
----------------------- ------------------ -------------
`~.Generator.integers` `randint`, Use the ``endpoint`` kwarg to
`random_integers` adjust the inclusion or exclusion
of the ``high`` interval endpoint.
======================= ================== =============
* The normal, exponential and gamma generators use 256-step Ziggurat
methods which are 2-10 times faster than NumPy's default implementation in
`~.Generator.standard_normal`, `~.Generator.standard_exponential` or
`~.Generator.standard_gamma`. Because of the change in algorithms, it is not
possible to reproduce the exact random values using `Generator` for these
distributions or any distribution method that relies on them.
.. ipython:: python
import numpy.random
rng = np.random.default_rng()
%timeit -n 1 rng.standard_normal(100000)
%timeit -n 1 numpy.random.standard_normal(100000)
.. ipython:: python
%timeit -n 1 rng.standard_exponential(100000)
%timeit -n 1 numpy.random.standard_exponential(100000)
.. ipython:: python
%timeit -n 1 rng.standard_gamma(3.0, 100000)
%timeit -n 1 numpy.random.standard_gamma(3.0, 100000)
* `~.Generator.integers` is now the canonical way to generate integer
random numbers from a discrete uniform distribution. This replaces both
`randint` and the deprecated `random_integers`.
* The `rand` and `randn` methods are only available through the legacy
`~.RandomState`.
* `Generator.random` is now the canonical way to generate floating-point
random numbers, which replaces `RandomState.random_sample`,
`sample`, and `ranf`, all of which were aliases. This is consistent with
Python's `random.random`.
* All bit generators can produce doubles, uint64s and
uint32s via CTypes (`~PCG64.ctypes`) and CFFI (`~PCG64.cffi`).
This allows these bit generators to be used in numba.
* The bit generators can be used in downstream projects via
Cython.
* All bit generators use `SeedSequence` to :ref:`convert seed integers to
initialized states <seeding_and_entropy>`.
* Optional ``dtype`` argument that accepts ``np.float32`` or ``np.float64``
to produce either single or double precision uniform random variables for
select distributions. `~.Generator.integers` accepts a ``dtype`` argument
with any signed or unsigned integer dtype.
* Uniforms (`~.Generator.random` and `~.Generator.integers`)
* Normals (`~.Generator.standard_normal`)
* Standard Gammas (`~.Generator.standard_gamma`)
* Standard Exponentials (`~.Generator.standard_exponential`)
.. ipython:: python
rng = np.random.default_rng()
rng.random(3, dtype=np.float64)
rng.random(3, dtype=np.float32)
rng.integers(0, 256, size=3, dtype=np.uint8)
* Optional ``out`` argument that allows existing arrays to be filled for
select distributions
* Uniforms (`~.Generator.random`)
* Normals (`~.Generator.standard_normal`)
* Standard Gammas (`~.Generator.standard_gamma`)
* Standard Exponentials (`~.Generator.standard_exponential`)
This allows multithreading to fill large arrays in chunks using suitable
BitGenerators in parallel.
.. ipython:: python
rng = np.random.default_rng()
existing = np.zeros(4)
rng.random(out=existing[:2])
print(existing)
* Optional ``axis`` argument for methods like `~.Generator.choice`,
`~.Generator.permutation` and `~.Generator.shuffle` that controls which
axis an operation is performed over for multi-dimensional arrays.
.. ipython:: python
rng = np.random.default_rng()
a = np.arange(12).reshape((3, 4))
a
rng.choice(a, axis=1, size=5)
rng.shuffle(a, axis=1) # Shuffle in-place
a
* Added a method to sample from the complex normal distribution
(`~.Generator.complex_normal`)
|