pytutorial/numpy/random/README.md
David Rotermund 047a245148
Update README.md
Signed-off-by: David Rotermund <54365609+davrot@users.noreply.github.com>
2023-12-13 18:05:40 +01:00

210 lines
8.8 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Random numbers the non-legacy way
{:.no_toc}
<nav markdown="1" class="toc-class">
* TOC
{:toc}
</nav>
## Goal
If you don't see something like **np.random.default_rng()** in your code then you are probably using the old [Legacy Random Generation](https://numpy.org/doc/stable/reference/random/legacy.html#legacy-random-generation).
**Don't use the [legacy](https://numpy.org/doc/stable/reference/random/legacy.html) methods** for new source code!!!
**numpy.random.random() == old == bad == don't use**
Do it like this:
```python
import numpy as np
rng = np.random.default_rng()
random_values = rng.random(size=(2, 10))
```
Questions to [David Rotermund](mailto:davrot@uni-bremen.de)
## [Random Generator](https://numpy.org/doc/stable/reference/random/generator.html#random-generator)
### Typical usage
```python
import numpy as np
rng = np.random.default_rng()
random_values = rng.random(size=(2, 10))
print(random_values)
```
Output:
```
[[0.81103943 0.1110591 0.42978062 0.47818377 0.91138636 0.47051031
0.08662082 0.1643707 0.48717037 0.17870536]
[0.94499902 0.74089677 0.12221184 0.61603001 0.91198789 0.33900609
0.75832792 0.74465679 0.19940125 0.56674595]]
```
### With seed:
```python
import numpy as np
rng = np.random.default_rng(seed=23)
random_values = rng.random(size=(2, 10))
print(random_values)
```
Output:
```
[[0.69393308 0.64145822 0.12864422 0.11370805 0.65334552 0.85345711
0.20177913 0.21801864 0.71658464 0.47069967]
[0.41522193 0.3491478 0.06385375 0.45466617 0.30145328 0.38907675
0.54029782 0.68358969 0.62475238 0.74270445]]
```
## [Changing the random number generator](https://numpy.org/doc/stable/reference/random/bit_generators/index.html)
### Default
```python
import numpy as np
rng = np.random.default_rng()
print(rng) # -> Generator(PCG64)
```
If you don't like it there are other options:
|||
|---|---|
|[PCG64](https://numpy.org/doc/stable/reference/random/bit_generators/pcg64.html) -- **The default**| A fast generator that can be advanced by an arbitrary amount. See the documentation for advance. PCG-64 has a period of 2^128. See the PCG authors page for more details about this class of PRNG.|
|[MT19937](https://numpy.org/doc/stable/reference/random/bit_generators/mt19937.html)| The standard Python BitGenerator. Adds a MT19937.jumped function that returns a new generator with state as-if 2^128 draws have been made.|
|[PCG64DXSM](https://numpy.org/doc/stable/reference/random/bit_generators/pcg64dxsm.html)| An upgraded version of PCG-64 with better statistical properties in parallel contexts. See Upgrading PCG64 with PCG64DXSM for more information on these improvements.|
|[Philox](https://numpy.org/doc/stable/reference/random/bit_generators/philox.html)|A counter-based generator capable of being advanced an arbitrary number of steps or generating independent streams. See the Random123 page for more details about this class of bit generators.|
|[SFC64](https://numpy.org/doc/stable/reference/random/bit_generators/sfc64.html)|A fast generator based on random invertible mappings. Usually the fastest generator of the four. See the SFC authors page for (a little) more detail.|
## [Distributions](https://numpy.org/doc/stable/reference/random/generator.html#distributions) (you will use)
The most important ones are in **bold**. If you see a function argument *out*, then you can reuse an existing np array (i.e. [in-place operation](https://numpy.org/doc/stable/reference/random/generator.html#in-place-vs-copy)) as target.
| | |
| ------------- |:-------------:|
|**[integers(low[, high, size, dtype, endpoint])](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.integers.html#numpy.random.Generator.integers)**| Return random integers from low (inclusive) to high (exclusive), or if endpoint=True, low (inclusive) to high (inclusive). |
|**[random([size, dtype, out])](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.random.html#numpy.random.Generator.random)** | Return random floats in the half-open interval [0.0, 1.0). |
|**[choice(a[, size, replace, p, axis, shuffle])](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.choice.html#numpy.random.Generator.choice)** | Generates a random sample from a given array |
|[bytes(length)](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.bytes.html#numpy.random.Generator.bytes) | Return random bytes. |
|[binomial(n, p[, size])](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.binomial.html#numpy.random.Generator.binomial) | Draw samples from a binomial distribution.|
|[multinomial(n, pvals[, size])](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.multinomial.html#numpy.random.Generator.multinomial) |Draw samples from a multinomial distribution. |
|[multivariate_normal(mean, cov[, size, ...])](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.multivariate_normal.html#numpy.random.Generator.multivariate_normal) | Draw random samples from a multivariate normal distribution.|
|**[normal([loc, scale, size])](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.normal.html#numpy.random.Generator.normal)** | Draw random samples from a normal (Gaussian) distribution.|
|**[poisson([lam, size])](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.poisson.html#numpy.random.Generator.poisson)** | Draw samples from a Poisson distribution.|
|[standard_normal([size, dtype, out])](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.standard_normal.html#numpy.random.Generator.standard_normal) | Draw samples from a standard Normal distribution (mean=0, stdev=1).|
|**[uniform([low, high, size])](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.uniform.html#numpy.random.Generator.uniform)** |Draw samples from a uniform distribution. |
### random
```python
import numpy as np
rng = np.random.default_rng()
random_values = rng.random(size=(2, 10))
print(random_values)
```
Output:
```
[[0.75309105 0.15751286 0.49454759 0.18204807 0.88459006 0.78685769
0.68525047 0.4000365 0.45317167 0.62412358]
[0.01082224 0.13257961 0.75638974 0.84886965 0.19755022 0.18697649
0.47064409 0.66128207 0.30285691 0.53465021]]
```
### integers
```python
import numpy as np
rng = np.random.default_rng()
random_values = rng.integers(
low=1, high=3, size=(2, 10), dtype=np.uint64, endpoint=True
)
print(random_values)
```
Output:
```
[[2 3 3 2 1 3 1 1 2 2]
[3 3 2 3 3 2 3 3 1 3]]
```
### choice
```python
import numpy as np
rng = np.random.default_rng()
p = np.array([1, 2, 3]).astype(np.float64)
p /= p.sum()
print(f"p: {p}")
random_values = rng.choice(a=p.shape[0], p=p, size=(2, 10))
print(random_values)
```
Output:
```
p: [0.16666667 0.33333333 0.5 ]
[[0 2 2 1 2 1 2 1 0 1]
[2 0 1 2 2 1 0 2 1 2]]
```
## [Permutations](https://numpy.org/doc/stable/reference/random/generator.html#permutations)
| | |
| ------------- |:-------------:|
|[shuffle(x[, axis])](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.shuffle.html#numpy.random.Generator.shuffle)|Modify an array or sequence in-place by shuffling its contents.|
|[permutation(x[, axis])](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.permutation.html#numpy.random.Generator.permutation)|Randomly permute a sequence, or return a permuted range.|
|[permuted(x[, axis, out])](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.permuted.html#numpy.random.Generator.permuted)|Randomly permute x along axis axis.|
|method |copy/in-place | [ axis handling](https://numpy.org/doc/stable/reference/random/generator.html#handling-the-axis-parameter) |
| ------------- |:-------------:|:-------------:|
|shuffle|in-place|as if 1d|
|permutation|copy|as if 1d|
|permuted|either (use out for in-place)|axis independent|
### shuffle
```python
import numpy as np
rng = np.random.default_rng()
idx_randomized = np.arange(0, 10)
rng.shuffle(idx_randomized)
print(idx_randomized)
```
Output:
```
[0 2 8 9 5 4 3 6 1 7]
```
### permutation
```python
import numpy as np
rng = np.random.default_rng()
idx_randomized = rng.permutation(10)
print(idx_randomized)
```
Output:
```
[9 4 7 2 6 3 1 8 5 0]
```
### permuted
```python
import numpy as np
rng = np.random.default_rng()
idx = np.arange(0, 10)
idx_randomized = rng.permuted(idx)
print(idx_randomized)
```
Output:
```
[4 1 2 8 9 6 0 5 7 3]
```
## All Distributions
You need more distributions? [Go here.](https://numpy.org/doc/stable/reference/random/generator.html#distributions)
## Multithreaded Generation
The four core distribution (random, standard_normal, standard_exponential, and standard_gamma) can be used with multi-threading. Please look [here for an example](https://numpy.org/doc/stable/reference/random/multithreading.html#multithreaded-generation).