rand, randn, randint & random
The four workhorse functions of np.random — uniform floats, standard-normal floats, random integers — and exactly when to use each.
Watch the lesson
1 video on CodeWithMunnaX
Most random-data jobs need one of three things: a probability-like float between 0 and 1, a bell-curve value around an average, or a whole number in a range (dice rolls, runs, ball numbers). NumPy's legacy np.random module has one function for each, plus an alias.
Definition
np.random.rand(d0, d1, ...)returns floats drawn from the uniform distribution over [0, 1) — every value between 0 (included) and 1 (excluded) is equally likely.
np.random.randn(d0, d1, ...)returns floats drawn from the standard normal distribution — a bell curve with mean 0 and standard deviation 1, so values can be negative.
np.random.randint(low, high=None, size=None)returns random integers fromlow(inclusive) tohigh(exclusive). If only one number is given, the range is0to that number (exclusive).
np.random.random(size)is the same asrand, but takes the shape as one tuple instead of separate numbers.
- Uniform — flat: no value is more likely than another.
- [0, 1) — the square bracket means 0 can appear, the round bracket means 1 never appears.
- Standard normal — "standard" means mean 0, std 1. About 68% of values fall between −1 and 1, and about 95% between −2 and 2.
- Exclusive high — exactly like Python's
range():randint(1, 7)gives 1–6, a perfect dice.
Syntax
python
np.random.rand(d0, d1, ..., dn) # shape as separate ints
np.random.randn(d0, d1, ..., dn) # shape as separate ints
np.random.randint(low, high=None, size=None, dtype=int)
np.random.random(size=None) # shape as ONE tuple| Function | Parameter | Meaning | Default |
|---|---|---|---|
rand / randn | d0, d1, ... | Size of each dimension, passed separately (rand(2, 3)) | none → returns a single float |
randint | low | Smallest possible integer (or the exclusive upper bound if high is missing) | — required |
randint | high | One more than the largest possible integer | None → range is 0 .. low-1 |
randint | size | Output shape: an int or a tuple like (2, 4) | None → single int |
randint | dtype | Integer type of the result | int (int64) |
random | size | Output shape as an int or tuple | None → single float |
Example — rand: uniform floats in [0, 1)
python
import numpy as np
np.random.seed(42)
print(np.random.rand()) # one float in [0, 1)
print(np.random.rand(4)) # 1D: 4 floats
print(np.random.rand(2, 3)) # 2D: 2 rows x 3 columnstext
0.3745401188473625
[0.95071431 0.73199394 0.59865848 0.15601864]
[[0.15599452 0.05808361 0.86617615]
[0.60111501 0.70807258 0.02058449]]How it works: with no arguments you get a plain Python-style float. Each extra argument adds a dimension: rand(2, 3) → shape (2, 3). Notice the shape is not a tuple here.
Example — randn: the standard bell curve
python
np.random.seed(42)
z = np.random.randn(6)
print(z.round(3))
print(np.random.randn(2, 2).round(3))text
[ 0.497 -0.138 0.648 1.523 -0.234 -0.234]
[[ 1.579 0.767]
[-0.469 0.543]]Values cluster around 0 and can be negative. To get a bell curve with your own mean and spread, scale and shift: mean + std * randn(...).
python
np.random.seed(42)
z = np.random.randn(5)
scores = 35 + 12 * z # shift to mean 35, stretch to std 12
print(scores.round(1))text
[41. 33.3 42.8 53.3 32.2]Example — randint: whole numbers in a range
python
np.random.seed(42)
print(np.random.randint(1, 7, size=10)) # dice: 1..6
print(np.random.randint(0, 120, size=(2, 4))) # IPL scores, 2 x 4
print(np.random.randint(5)) # one int from 0..4text
[4 5 3 5 5 2 3 3 3 5]
[[ 99 103 23 2]
[ 21 52 1 87]]
3How it works: randint(1, 7) can return 1, 2, 3, 4, 5 or 6 — never 7. Here size is a tuple, unlike rand.
Example — random: rand with a tuple
python
np.random.seed(42)
print(np.random.random(3))
print(np.random.random((2, 2)))text
[0.37454012 0.95071431 0.73199394]
[[0.59865848 0.15601864]
[0.15599452 0.05808361]]Same numbers as rand with the same seed — it is literally the same generator, only the way you pass the shape differs.
Comparison — rand vs randn vs randint vs random
rand | randn | randint | random | |
|---|---|---|---|---|
| Returns | floats | floats | integers | floats |
| Range | [0, 1) | (−∞, +∞), mostly −3 to 3 | low to high − 1 | [0, 1) |
| Distribution | uniform (flat) | standard normal (bell) | uniform over integers | uniform (flat) |
| Mean | 0.5 | 0 | (low + high − 1) / 2 | 0.5 |
| Shape passed as | rand(2, 3) | randn(2, 3) | size=(2, 3) | random((2, 3)) |
| Typical use | probabilities, percentages | noise, z-scores | dice, runs, indices | same as rand |
Proof with 100,000 draws of each:
text
rand -> min 0.0000033 max 0.9999780 mean 0.500
randn -> min -4.6946 max 4.2859 mean 0.010 std 0.998
randint -> min 1 max 6 mean 3.497Common mistakes
- ❌
np.random.rand((2, 3))→TypeError. ✅np.random.rand(2, 3)ornp.random.random((2, 3)). - ❌
np.random.randint(1, 6)for a dice — it never returns 6. ✅randint(1, 7). - ❌ Using
randnwhen values must be positive (runs, prices). ✅ Userandint/uniform, or clip:np.clip(x, 0, None). - ❌ Expecting
randto ever return exactly1.0. ✅ The upper end is excluded.
Interview tip
Q: What is the difference between np.random.rand and np.random.randn?
A: rand draws from a uniform distribution on [0, 1) — all values equally likely, never negative. randn draws from the standard normal distribution (mean 0, std 1) — values cluster near 0 and can be negative.
Key points to remember
- rand(d0, d1, ...) gives uniform floats in [0, 1) — shape passed as separate numbers.
- randn(d0, d1, ...) gives standard-normal floats: mean 0, std 1, can be negative.
- randint(low, high, size) gives integers from low up to high − 1 (high is exclusive, like range).
- random(size) is rand with the shape given as one tuple.
- Scale randn to any bell curve with mean + std * np.random.randn(n).
- With only one argument, randint(n) returns integers from 0 to n − 1.
Try it yourself
All four functions side by side
Check the ranges with 100,000 draws
Practice: random IPL scorecard
Revision Flashcards
Tap a card to flip it and see the answer.
