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:
BitGenerator
Generator
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 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 What’s New or Different for a complete list of improvements and differences from the legacy Randomstate.
RandomState
Randomstate
For convenience and backward compatibility, a single RandomState instance’s methods are imported into the numpy.random namespace, see Legacy Random Generation for the complete list.
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.
default_rng
PCG64
MT19937
# 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 a 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
gen.bit_generator
Notes
random_sample,
random_sample
random
Compatible with random.random
random.random
rand
randint,
randint
integers
Add an endpoint kwarg
endpoint
random_integers
tomaxint
removed
Use integers(0, np.iinfo(np.int_).max, endpoint=False)
integers(0, np.iinfo(np.int_).max,
endpoint=False)
seed
Use SeedSequence.spawn
SeedSequence.spawn
See What’s 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
try: rg_integers = rg.integers except AttributeError: rg_integers = rg.randint a = rg_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.
SeedSequence
from numpy.random import Generator, PCG64 rg = Generator(PCG64(12345)) rg.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'>
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 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.
random generator
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 >>> rg = default_rng(12345) >>> print(rg) Generator(PCG64) >>> print(rg.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 >>> rg = Generator(PCG64(12345)) >>> print(rg) 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 >>> rg = Generator(MT19937(12345)) >>> print(rg) Generator(MT19937)
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.
RandomState.gamma
RandomState.standard_t
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 prevision uniform random variables for select distributions
dtype
np.float32
np.float64
Optional out argument that allows existing arrays to be filled for select distributions
out
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.
PCG64.ctypes
PCG64.cffi
The bit generators can be used in downstream projects via 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.integers
randn
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.
Generator.random
RandomState.random_sample
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.
axis
Generator.choice
Generator.permutation
Generator.shuffle
See What’s New or Different for a complete list of improvements and differences from the traditional Randomstate.
The included generators can be used in parallel, distributed applications in one of three ways:
SeedSequence spawning
Independent Streams
Jumping the BitGenerator state
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.