NumPy Random: Generators, Seeds, and Reproducible Samples

Quick answer: Use NumPy’s Generator API to create explicit random streams and distribution samples. Seed generators for reproducible tests or experiments, record the bit generator and stream policy, and keep numerical randomness separate from cryptographic secret generation.

Python Pool infographic showing NumPy's default random generator producing independent seeded sample streams for a reproducible experiment
NumPy’s Generator API makes random state explicit; use seeds for reproducible experiments and keep statistical randomness separate from security token generation.

NumPy’s modern random API starts with np.random.default_rng(). It returns a Generator object that creates random floats, integers, samples, permutations, and distribution data for arrays.

The official NumPy documentation covers the random sampling module and the Generator API. Python’s secrets module is the better standard-library choice for security tokens.

Older examples often use module-level calls such as np.random.seed() and np.random.randint(). Those still exist for compatibility, but new code should usually create a generator with default_rng() and pass that generator to the code that needs random numbers.

Seeding is for reproducibility, not security. A fixed seed is useful in tutorials, tests, simulations, and notebooks because it makes output repeatable. Do not use NumPy random output for passwords, API keys, reset tokens, or cryptographic secrets.

Shape matters. Most generator methods accept size, which can be an integer or a tuple. A tuple such as (2, 3) creates a two-row, three-column array.

Use distribution-specific methods when the statistical meaning matters. random() creates uniform floats in the half-open interval [0, 1). normal() creates samples from a normal distribution with a chosen mean and standard deviation.

Keep one generator near the workflow that owns the randomness. Passing a generator into functions avoids hidden global state and makes tests easier to repeat.

This is especially important in notebooks and data pipelines. If every cell or helper function changes the module-level random state, results can depend on execution order. A local generator makes that dependency explicit.

Use fixed seeds in examples, regression tests, and debugging sessions. Remove or change those seeds when the goal is to run independent simulations. A fixed seed is useful for explaining behavior, but it intentionally repeats the same pseudo-random sequence.

Think carefully about replacement when sampling. Sampling with replacement means an item can appear more than once. Sampling without replacement is closer to drawing cards from a deck, where a selected item is no longer available for the same draw.

For generated test arrays, record the distribution, shape, and seed together. That makes it easier for another developer to reproduce the same input and understand whether the numbers were uniform, normal, integer, or sampled labels.

When teaching or reviewing random examples, avoid saying the values are completely random. NumPy generators produce pseudo-random numbers designed for numerical work. They are excellent for simulations and tests, but they are not a security boundary.

For security tokens, use secrets or a cryptography library instead of NumPy.

That keeps simulation randomness separate from authentication and authorization decisions.

Keep that boundary explicit.

Create Random Floats

default_rng() creates a generator object.

import numpy as np

rng = np.random.default_rng(42)
values = rng.random(3)

print(np.round(values, 3))

random(3) returns three floats between zero and one.

The seed makes the example output repeatable.

Rounding is used only to make the printed result easier to read.

Create Random Integers

Use integers() for random whole numbers.

import numpy as np

rng = np.random.default_rng(7)
values = rng.integers(1, 10, size=(2, 3))

print(values)

The low value is included.

The high value is excluded.

The shape argument creates a 2 by 3 array.

Python Pool infographic showing NumPy Generator, bit generator, state, and random samples
Random generator: NumPy Generator, bit generator, state, and random samples.

Sample Items With choice

choice() samples from an array or sequence.

import numpy as np

rng = np.random.default_rng(1)
colors = np.array(["red", "green", "blue", "gold"])
sample = rng.choice(colors, size=2, replace=False)

print(sample)

replace=False means the same item cannot be selected twice.

This is useful for sampling labels, rows, IDs, or other existing values.

Use replace=True when repeated selections are allowed.

Create Normal Samples

Use normal() for normally distributed values.

import numpy as np

rng = np.random.default_rng(5)
values = rng.normal(loc=10, scale=2, size=4)

print(np.round(values, 2))

loc sets the center of the distribution.

scale sets the standard deviation.

Use distribution parameters deliberately so the generated data matches the simulation or test case.

Permute Without Changing The Original

permutation() returns shuffled data while leaving the input unchanged.

import numpy as np

rng = np.random.default_rng(3)
items = np.array([1, 2, 3, 4])
permuted = rng.permutation(items)

print(permuted)
print(items)

The first print shows the permuted result.

The second print shows that the original array still has its original order.

Use shuffle() instead when in-place shuffling is intended.

Python Pool infographic mapping a seed through a generator to repeatable random values
Seed state: A seed through a generator to repeatable random values.

Repeat Results With A Seed

Using the same seed creates the same sequence from a new generator.

import numpy as np

left = np.random.default_rng(99).integers(0, 5, size=4)
right = np.random.default_rng(99).integers(0, 5, size=4)

print(np.array_equal(left, right))

This is useful for repeatable tests and examples.

For independent simulation runs, use different seeds or seed-management tools suited to the project.

In short, prefer default_rng() and Generator methods for new NumPy random code, use seeds for reproducibility, use size for shapes, choose the distribution method that matches the problem, and avoid NumPy random output for security-sensitive secrets.

Prefer Generator

Create a Generator with default_rng and pass it into functions that need randomness. This makes state a visible dependency and avoids hidden coupling through global random calls.

Python Pool infographic comparing uniform, normal, integers, choice, and distribution parameters
Distributions: Uniform, normal, integers, choice, and distribution parameters.

Choose A Distribution

Select normal, uniform, integer, choice, permutation, or another distribution based on the model. Validate bounds, shape, dtype, and whether replacement is allowed.

Make Runs Reproducible

A seed can reproduce a test or experiment when the generator, NumPy version, call order, and stream allocation are controlled. Store those details with the result when auditability matters.

Split Independent Streams

Parallel simulations need deliberate stream allocation rather than every worker reusing the same seed. Use the Generator and SeedSequence mechanisms appropriate for the workload and verify independence assumptions.

Python Pool infographic testing independent streams, state restore, bounds, dtype, and leakage
Random checks: Independent streams, state restore, bounds, dtype, and leakage.

Keep Security Separate

NumPy random is designed for simulation and numerical sampling, not passwords, reset links, keys, or authentication tokens. Use Python’s secrets module or a security library for those requirements.

Test Statistical Contracts

Test shape, bounds, seeded repeatability, independent stream setup, invalid arguments, dtype, empty outputs, and a basic distribution sanity check without overclaiming from tiny samples.

The official NumPy Generator documentation describes the modern random API. Related Python Pool references include NumPy arrays and tests.

For reproducible numerical workflows, compare NumPy array shapes, seed and distribution tests, and sample sequences before generating random data.

Frequently Asked Questions

How should I generate random values with NumPy?

Create a NumPy random Generator and call the distribution method that matches the model instead of relying on shared global state.

How do I make NumPy results reproducible?

Use a documented seed or seed sequence and record the generator configuration with the experiment or test.

Is NumPy random secure for passwords?

No. NumPy generators are for numerical simulation and sampling, not cryptographic secrets or authentication tokens.

Why did my random results change after a refactor?

The generator state, call order, bit generator, seed, or parallel stream allocation may have changed; make those dependencies explicit.

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted