Module 5 · Lesson 5
Random Number Generation with the Generator API
Modern NumPy code should create an explicit Generator instead of using
the legacy global functions (np.random.seed, np.random.rand, …):
rng = np.random.default_rng(seed=42)
A Generator gives you reproducibility (same seed -> same sequence)
and independent streams (two default_rng() calls never silently
share or clobber global state, which matters once you have multiple
pieces of code sampling randomness at once). The most common methods:
| Method | Produces |
|---|---|
rng.random(size) | floats uniform in [0, 1) |
rng.integers(low, high, size) | integers in [low, high) |
rng.normal(loc, scale, size) | samples from a normal distribution |
rng.choice(a, size, replace=...) | random samples from an array |
For rng.choice, replace=True (the default) can pick the same element
more than once; replace=False samples without repeats, like dealing
cards from a deck instead of rolling the same die repeatedly.
rng = np.random.default_rng(seed=42)
print(rng.random(3))
print(rng.integers(0, 10, size=5))
print(rng.normal(loc=0.0, scale=1.0, size=3))
# same seed -> same sequence, every time
rng_a = np.random.default_rng(seed=7)
rng_b = np.random.default_rng(seed=7)
print(np.array_equal(rng_a.random(5), rng_b.random(5)))
samples = np.random.default_rng(0).normal(size=10_000)
plt.hist(samples, bins=30)
plt.title("10,000 samples from a standard normal distribution")
plt.show()
Output:
[0.77395605 0.43887844 0.85859792]
[0 6 2 0 5]
[ 0.1278404 -0.31624259 -0.01680116]
True
Reproducible dice rolls
Write roll_dice(n_rolls, seed) that returns an array of n_rolls
simulated six-sided die rolls (integers 1-6 inclusive), using
np.random.default_rng(seed). The same seed must always produce the
same sequence.
💡 Hint
np.random.default_rng(seed).integers(1, 7, size=n_rolls) — remember integers's upper bound is exclusive, so use 7 to include 6.
✅ Solution
def roll_dice(n_rolls, seed):
rng = np.random.default_rng(seed)
return rng.integers(1, 7, size=n_rolls)
Shuffle without replacement
Write random_sample_no_replace(arr, k, seed) that returns k elements
randomly chosen from arr without replacement (no duplicates), using
rng.choice with the right arguments.
💡 Hint
np.random.default_rng(seed).choice(arr, size=k, replace=False).
✅ Solution
def random_sample_no_replace(arr, k, seed):
rng = np.random.default_rng(seed)
return rng.choice(arr, size=k, replace=False)