---
jupytext:
  formats: content_md///md:myst,content///ipynb
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
    jupytext_version: 1.13.8
kernelspec:
  display_name: Python 3 (ipykernel)
  language: python
  name: python3
---

(managing-data:numpy:random-numbers)=
# Random Numbers

In data science contexts random numbers are important for simulating data and for selecting random subsets of data.
NumPy provides a submodule `random` for creating arrays of (pseudo-)random numbers.

```{code-cell} ipython3
import numpy as np
```

## Random Number Generators

NumPy supports several different algorithms for generating random numbers. For our purposes choice of algorithm does not matter (for crypto applications it matters!). Luckily NumPy provides a default one.

We first have to create a random number generator object (or get the default one) and initialize it with a seed. The seed determines the sequence of generated random numbers. Using a fixed seed is important if we need reproducable results (when testing things, for instance).

```{code-cell} ipython3
rng = np.random.default_rng(123)    # use some integer as seed here
```

## Getting Random Numbers

Random numbers may follow different distributions. NumPy provides many standard distributions, see [Random Generator](https://numpy.org/doc/stable/reference/random/generator.html#simple-random-data) in NumPy's documentation.

```{code-cell} ipython3
# random integers (arguments: first, last + 1, shape)
a = rng.integers(23, 42, (4, 10))

print(a)
```

```{code-cell} ipython3
# uniformly distributed floats in [0, 1)
a = rng.random((4, 4))

print(a)
```

```{code-cell} ipython3
# permutation of an array
a = np.array([1, 2, 3, 4 ,5])
b = rng.permutation(a)

print(b)
```
