# Random sampling (`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 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`.

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.

## 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`.

    # 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 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:
        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`.

    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` 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 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 What’s 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 one of three ways:

- SeedSequence spawning

- Independent Streams

- Jumping the BitGenerator state

Users with a very large amount of parallelism will want to consult Upgrading PCG64 with PCG64DXSM.

## Concepts

- Random Generator
- Legacy Generator (RandomState)
- Bit Generators
- Seeding and Entropy
- Upgrading PCG64 with PCG64DXSM

## Features

- Parallel Applications
  - `SeedSequence` spawning
  - Independent Streams
  - Jumping the BitGenerator state
- Multithreaded Generation
- What’s New or Different
- Comparing Performance
  - Recommendation
  - Timings
  - Performance on different Operating Systems
- C API for random
- Examples of using Numba, Cython, CFFI
  - Numba
  - Cython
  - CFFI
  - New Bit Generators
  - Examples

### 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.

previous

numpy.RankWarning

next

Random Generator