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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
|
.. _numpyrandom:
.. py:module:: numpy.random
.. currentmodule:: numpy.random
Random sampling (:mod:`numpy.random`)
=====================================
Numpy's random number routines produce pseudo random numbers using
combinations of a `BitGenerator` to create sequences and a `Generator`
to use those sequences to sample from different statistical distributions:
* BitGenerators: Objects that generate random numbers. These are typically
unsigned integer words filled with sequences of either 32 or 64 random bits.
* Generators: Objects that transform sequences of random bits from a
BitGenerator into sequences of numbers that follow a specific probability
distribution (such as uniform, Normal or Binomial) within a specified
interval.
Since Numpy version 1.17.0 the Generator can be initialized with a
number of different BitGenerators. It exposes many different probability
distributions. See `NEP 19 <https://www.numpy.org/neps/
nep-0019-rng-policy.html>`_ for context on the updated random Numpy number
routines. The legacy `RandomState` random number routines are still
available, but limited to a single BitGenerator. See :ref:`new-or-different`
for a complete list of improvements and differences from the legacy
``RandomState``.
For convenience and backward compatibility, a single `RandomState`
instance's methods are imported into the numpy.random namespace, see
:ref:`legacy` for the complete list.
.. _random-quick-start:
Quick Start
-----------
Call `default_rng` to get a new instance of a `Generator`, then call its
methods to obtain samples from different distributions. By default,
`Generator` uses bits provided by `PCG64` which has better statistical
properties than the legacy `MT19937` used in `RandomState`.
.. code-block:: python
# Do this (new version)
from numpy.random import default_rng
rng = default_rng()
vals = rng.standard_normal(10)
more_vals = rng.standard_normal(10)
# instead of this (legacy version)
from numpy import random
vals = random.standard_normal(10)
more_vals = random.standard_normal(10)
`Generator` can be used as a replacement for `RandomState`. Both class
instances hold an internal `BitGenerator` instance to provide the bit
stream, it is accessible as ``gen.bit_generator``. Some long-overdue API
cleanup means that legacy and compatibility methods have been removed from
`Generator`
=================== ============== ============
`RandomState` `Generator` Notes
------------------- -------------- ------------
``random_sample``, ``random`` Compatible with `random.random`
``rand``
------------------- -------------- ------------
``randint``, ``integers`` Add an ``endpoint`` kwarg
``random_integers``
------------------- -------------- ------------
``tomaxint`` removed Use ``integers(0, np.iinfo(np.int_).max,``
``endpoint=False)``
------------------- -------------- ------------
``seed`` removed Use `SeedSequence.spawn`
=================== ============== ============
See :ref:`new-or-different` for more information.
Something like the following code can be used to support both ``RandomState``
and ``Generator``, with the understanding that the interfaces are slightly
different
.. code-block:: python
try:
rng_integers = rng.integers
except AttributeError:
rng_integers = rng.randint
a = rng_integers(1000)
Seeds can be passed to any of the BitGenerators. The provided value is mixed
via `SeedSequence` to spread a possible sequence of seeds across a wider
range of initialization states for the BitGenerator. Here `PCG64` is used and
is wrapped with a `Generator`.
.. code-block:: python
from numpy.random import Generator, PCG64
rng = Generator(PCG64(12345))
rng.standard_normal()
Here we use `default_rng` to create an instance of `Generator` to generate a
random float:
>>> import numpy as np
>>> rng = np.random.default_rng(12345)
>>> print(rng)
Generator(PCG64)
>>> rfloat = rng.random()
>>> rfloat
0.22733602246716966
>>> type(rfloat)
<class 'float'>
Here we use `default_rng` to create an instance of `Generator` to generate 3
random integers between 0 (inclusive) and 10 (exclusive):
>>> import numpy as np
>>> rng = np.random.default_rng(12345)
>>> rints = rng.integers(low=0, high=10, size=3)
>>> rints
array([6, 2, 7])
>>> type(rints[0])
<class 'numpy.int64'>
Introduction
------------
The new infrastructure takes a different approach to producing random numbers
from the `RandomState` object. Random number generation is separated into
two components, a bit generator and a random generator.
The `BitGenerator` has a limited set of responsibilities. It manages state
and provides functions to produce random doubles and random unsigned 32- and
64-bit values.
The `random generator <Generator>` takes the
bit generator-provided stream and transforms them into more useful
distributions, e.g., simulated normal random values. This structure allows
alternative bit generators to be used with little code duplication.
The `Generator` is the user-facing object that is nearly identical to the
legacy `RandomState`. It accepts a bit generator instance as an argument.
The default is currently `PCG64` but this may change in future versions.
As a convenience NumPy provides the `default_rng` function to hide these
details:
>>> from numpy.random import default_rng
>>> rng = default_rng(12345)
>>> print(rng)
Generator(PCG64)
>>> print(rng.random())
0.22733602246716966
One can also instantiate `Generator` directly with a `BitGenerator` instance.
To use the default `PCG64` bit generator, one can instantiate it directly and
pass it to `Generator`:
>>> from numpy.random import Generator, PCG64
>>> rng = Generator(PCG64(12345))
>>> print(rng)
Generator(PCG64)
Similarly to use the older `MT19937` bit generator (not recommended), one can
instantiate it directly and pass it to `Generator`:
>>> from numpy.random import Generator, MT19937
>>> rng = Generator(MT19937(12345))
>>> print(rng)
Generator(MT19937)
What's New or Different
~~~~~~~~~~~~~~~~~~~~~~~
.. warning::
The Box-Muller method used to produce NumPy's normals is no longer available
in `Generator`. It is not possible to reproduce the exact random
values using Generator for the normal distribution or any other
distribution that relies on the normal such as the `RandomState.gamma` or
`RandomState.standard_t`. If you require bitwise backward compatible
streams, use `RandomState`.
* The Generator's normal, exponential and gamma functions use 256-step Ziggurat
methods which are 2-10 times faster than NumPy's Box-Muller or inverse CDF
implementations.
* Optional ``dtype`` argument that accepts ``np.float32`` or ``np.float64``
to produce either single or double precision uniform random variables for
select distributions
* Optional ``out`` argument that allows existing arrays to be filled for
select distributions
* All BitGenerators can produce doubles, uint64s and uint32s via CTypes
(`PCG64.ctypes`) and CFFI (`PCG64.cffi`). This allows the bit generators
to be used in numba.
* The bit generators can be used in downstream projects via
:ref:`Cython <random_cython>`.
* `Generator.integers` is now the canonical way to generate integer
random numbers from a discrete uniform distribution. The ``rand`` and
``randn`` methods are only available through the legacy `RandomState`.
The ``endpoint`` keyword can be used to specify open or closed intervals.
This replaces both ``randint`` and the deprecated ``random_integers``.
* `Generator.random` is now the canonical way to generate floating-point
random numbers, which replaces `RandomState.random_sample`,
`RandomState.sample`, and `RandomState.ranf`. This is consistent with
Python's `random.random`.
* All BitGenerators in numpy use `SeedSequence` to convert seeds into
initialized states.
* The addition of an ``axis`` keyword argument to methods such as
`Generator.choice`, `Generator.permutation`, and `Generator.shuffle`
improves support for sampling from and shuffling multi-dimensional arrays.
See :ref:`new-or-different` for a complete list of improvements and
differences from the traditional ``Randomstate``.
Parallel Generation
~~~~~~~~~~~~~~~~~~~
The included generators can be used in parallel, distributed applications in
a number of ways:
* :ref:`seedsequence-spawn`
* :ref:`sequence-of-seeds`
* :ref:`independent-streams`
* :ref:`parallel-jumped`
Users with a very large amount of parallelism will want to consult
:ref:`upgrading-pcg64`.
Concepts
--------
.. toctree::
:maxdepth: 1
generator
Legacy Generator (RandomState) <legacy>
BitGenerators, SeedSequences <bit_generators/index>
Upgrading PCG64 with PCG64DXSM <upgrading-pcg64>
Features
--------
.. toctree::
:maxdepth: 2
Parallel Applications <parallel>
Multithreaded Generation <multithreading>
new-or-different
Comparing Performance <performance>
c-api
Examples of using Numba, Cython, CFFI <extending>
Original Source of the Generator and BitGenerators
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This package was developed independently of NumPy and was integrated in version
1.17.0. The original repo is at https://github.com/bashtage/randomgen.
|