np.random.rand() returns uniformly sampled floats from zero inclusive to one exclusive. Pass separate dimension lengths to create an array of the required shape. The legacy API is useful for reading existing code; for new code, prefer a local Generator and its random method.
| Call | Result |
|---|---|
np.random.rand() | One Python float |
np.random.rand(4) | 1D array, shape (4,) |
np.random.rand(4, 3) | 2D array, shape (4, 3) |
rng.random((4, 3)) | Modern Generator method using a tuple shape |
Examples use seeds for practice. Exact Generator output can vary across NumPy versions; replay checks compare runs in the current environment.
Show Table of Contentsnp.random.rand draws uniformly from zero inclusive to one exclusive. It returns a Python float when no dimensions are supplied. A seed makes this legacy example reproducible for practice; without it, values change across runs.
import numpy as np
np.random.seed(42)
my_data = np.random.rand()
print(my_data)
print("Type:", type(my_data).__name__)
assert isinstance(my_data, float) and 0 <= my_data < 1Expected output
0.3745401188473625
Type: floatrand(4) creates four values with shape (4,). The argument is the length of the dimension, not the number of dimensions.
np.random.seed(42)
my_data = np.random.rand(4)
print(my_data)
print("Shape:", my_data.shape)
assert my_data.shape == (4,)
assert ((my_data >= 0) & (my_data < 1)).all()Expected output
[0.37454012 0.95071431 0.73199394 0.59865848]
Shape: (4,)rand(4, 3) creates four rows and three columns. Each entry is a sampled float. Review array shape and axis reduction when summarizing the result.
np.random.seed(42)
my_data = np.random.rand(4, 3)
print(my_data)
print("Shape / size / dtype:", my_data.shape, my_data.size, my_data.dtype)
assert my_data.shape == (4, 3) and my_data.size == 12Expected output
[[0.37454012 0.95071431 0.73199394]
[0.59865848 0.15601864 0.15599452]
[0.05808361 0.86617615 0.60111501]
[0.70807258 0.02058449 0.96990985]]
Shape / size / dtype: (4, 3) 12 float64The original shape (1, 2, 3, 4) has four axes and 24 elements. Assign an interpretation to each axis before selecting or reducing data. NumPy itself does not attach business labels to dimensions.
np.random.seed(42)
my_data = np.random.rand(1, 2, 3, 4)
print(my_data)
print("Shape / ndim / size:", my_data.shape, my_data.ndim, my_data.size)
assert my_data.shape == (1, 2, 3, 4)
assert my_data.ndim == 4 and my_data.size == 24Expected output
[[[[0.37454012 0.95071431 0.73199394 0.59865848]
[0.15601864 0.15599452 0.05808361 0.86617615]
[0.60111501 0.70807258 0.02058449 0.96990985]]
[[0.83244264 0.21233911 0.18182497 0.18340451]
[0.30424224 0.52475643 0.43194502 0.29122914]
[0.61185289 0.13949386 0.29214465 0.36636184]]]]
Shape / ndim / size: (1, 2, 3, 4) 4 24For a shape tuple, unpack it with *. random_sample and Generator.random accept the tuple directly. Confusing these forms is a common TypeError.
shape = (2, 3)
try:
np.random.rand(shape)
except TypeError:
print("rand(shape_tuple): TypeError")
else:
raise AssertionError('Expected TypeError')
np.random.seed(12)
a = np.random.rand(*shape)
np.random.seed(12)
b = np.random.random_sample(shape)
print(a)
np.testing.assert_array_equal(a, b)Expected output
rand(shape_tuple): TypeError
[[0.15416284 0.7400497 0.26331502]
[0.53373939 0.01457496 0.91874701]]Dimension lengths must be nonnegative integers. A zero dimension gives an empty array. Validate user-supplied shapes and a memory budget before allocating large arrays.
empty = np.random.rand(0, 3)
print("Empty shape / size:", empty.shape, empty.size)
assert empty.shape == (0, 3)
for size in [-1, 2.5]:
try:
np.random.rand(size)
except (ValueError, TypeError) as error:
print("Rejected:", size, type(error).__name__)
else:
raise AssertionError('Expected invalid size')Expected output
Empty shape / size: (0, 3) 0
Rejected: -1 ValueError
Rejected: 2.5 TypeErrornp.random.seed resets the state used by legacy random functions. Other code drawing from that global state changes later results. Seed once for a continuing run rather than inside a loop. Modern local Generators avoid this shared-state dependency.
np.random.seed(24)
a = np.random.rand(4)
np.random.seed(24)
b = np.random.rand(4)
print("First:", a)
print("Replay matches:", np.array_equal(a, b))
np.testing.assert_array_equal(a, b)
restarted = []
for _ in range(3):
np.random.seed(24)
restarted.append(np.random.rand())
print("Restarting repeats:", restarted)
assert len(set(restarted)) == 1Expected output
First: [0.9600173 0.69951205 0.99986729 0.2200673 ]
Replay matches: True
Restarting repeats: [0.9600173033359185, 0.9600173033359185, 0.9600173033359185]Use default_rng(seed).random(size) for new sampling code. The size is a tuple for multiple axes. A Generator has its own state and is not reset by np.random.seed. The same seed does not promise the same sequence as the legacy API. See Generator, streams and replay.
rng = np.random.default_rng(42)
a = rng.random((4, 3))
print(a)
print("Shape:", a.shape)
replay = np.random.default_rng(42).random((4, 3))
np.testing.assert_array_equal(a, replay)
assert ((a >= 0) & (a < 1)).all()Expected output
[[0.77395605 0.43887844 0.85859792]
[0.69736803 0.09417735 0.97562235]
[0.7611397 0.78606431 0.12811363]
[0.45038594 0.37079802 0.92676499]]
Shape: (4, 3)Use low + (high - low) * u to scale [0, 1) samples, or use Generator.uniform directly. Floating-point rounding can affect strict endpoint interpretation after scaling; validate the range appropriate to your calculation.
rng = np.random.default_rng(15)
low, high = 10.0, 20.0
values = low + (high - low) * rng.random(5)
direct = rng.uniform(low, high, size=5)
print("Scaled:", np.round(values, 3))
print("Uniform method:", np.round(direct, 3))
assert ((values >= low) & (values <= high)).all()Expected output
Scaled: [16.927 18.158 13.444 10.448 15.716]
Uniform method: [11.462 17.188 13.454 14.57 19.759]rand produces floats, not integer counts. Rounding scaled uniforms can distort endpoint probabilities. For a die, draw integers from one inclusive to seven exclusive. See legacy randint().
rng = np.random.default_rng(22)
rolls = rng.integers(1, 7, size=12)
print(rolls)
assert rolls.dtype.kind in 'iu'
assert ((rolls >= 1) & (rolls <= 6)).all()Expected output
[5 3 4 2 6 1 2 4 1 3 1 6]rand is uniform on [0, 1); randn draws from a standard normal distribution and can return negative values or values above one. Generator equivalents are random and standard_normal. See randn().
rng = np.random.default_rng(31)
uniform = rng.random(6)
normal = rng.standard_normal(6)
print("Uniform:", np.round(uniform, 3))
print("Normal:", np.round(normal, 3))
assert ((uniform >= 0) & (uniform < 1)).all()Expected output
Uniform: [0.903 0.068 0.673 0.473 0.677 0.04 ]
Normal: [ 0.783 0.272 1.162 -0.938 1.776 1.202]Equal-width bins have equal probabilities for a uniform distribution, but observed counts fluctuate. A sample mean near 0.5 is expected for a large sample, not guaranteed exactly. One histogram is not a complete statistical quality test.
rng = np.random.default_rng(50)
values = rng.random(10000)
counts, edges = np.histogram(values, bins=np.linspace(0, 1, 6))
print("Bin boundaries:", edges)
print("Bin counts:", counts)
print("Sample mean:", round(float(values.mean()), 4))
assert counts.sum() == values.sizeExpected output
Bin boundaries: [0. 0.2 0.4 0.6 0.8 1. ]
Bin counts: [2004 2000 2015 2000 1981]
Sample mean: 0.5001Legacy rand returns float64 samples. For float32 output, Generator.random supports dtype directly. Casting already-generated values changes storage and precision; it does not reproduce the same stream as direct float32 generation. See dtype.
rng = np.random.default_rng(60)
a = rng.random((2, 3), dtype=np.float32)
print(a)
print("dtype / bytes:", a.dtype, a.nbytes)
assert a.dtype == np.dtype(np.float32)
assert a.nbytes == 24Expected output
[[0.17417222 0.32428378 0.39344412]
[0.02714634 0.9724468 0.05472088]]
dtype / bytes: float32 24Model a purchase as a uniform draw below a stated probability. This synthetic example uses three campaigns with probabilities 0.05, 0.10 and 0.20 and 5000 visitors per campaign. It demonstrates sampling, not an estimate based on actual analytics. Outcomes are independent under this toy model.
rng = np.random.default_rng(2026)
probabilities = np.array([0.05, 0.10, 0.20])
draws = rng.random((5000, 3))
purchased = draws < probabilities
counts = purchased.sum(axis=0)
rates = purchased.mean(axis=0)
print("Synthetic purchases:", counts)
print("Simulated rates:", np.round(rates, 4))
print("Assumed probabilities:", probabilities)
assert purchased.shape == (5000, 3)
assert ((rates >= 0) & (rates <= 1)).all()Expected output
Synthetic purchases: [230 477 953]
Simulated rates: [0.046 0.0954 0.1906]
Assumed probabilities: [0.05 0.1 0.2 ]Do not pass a tuple without unpacking it. Do not interpret dimension lengths as axis numbers. Use integer sampling for counts and a normal distribution when that model is intended. Avoid repeatedly resetting a seed inside a loop. Do not round raw draws before threshold decisions, because this changes their distribution. Record the seed and environment for replay. NumPy random functions are for sampling and simulation; use a security-specific generator for tokens.
Create a local Generator with seed 123 and draw shape (3, 4). Calculate a mean for each row and count values below 0.25 in each column. Recreate the generator to verify replay, then check shapes and bounds. The observed means and counts need not equal theoretical expectations exactly.
Reduce axis=1 for row means and axis=0 for column counts. Keep full-precision samples for the condition and round only the displayed means.
rng = np.random.default_rng(123)
values = rng.random((3, 4))
row_means = values.mean(axis=1)
column_counts = (values < 0.25).sum(axis=0)
replay = np.random.default_rng(123).random((3, 4))
print(values)
print("Row means:", np.round(row_means, 4))
print("Column counts below 0.25:", column_counts)
np.testing.assert_array_equal(values, replay)
assert row_means.shape == (3,) and column_counts.shape == (4,)
assert ((values >= 0) & (values < 1)).all()Expected output
[[0.68235186 0.05382102 0.22035987 0.18437181]
[0.1759059 0.81209451 0.923345 0.2765744 ]
[0.81975456 0.88989269 0.51297046 0.2449646 ]]
Row means: [0.2852 0.547 0.6169]
Column counts below 0.25: [1 1 1 2]Open in Google Colab View on GitHub
All sample data is embedded. Run the examples and practise uniform sampling, shapes and simulation. Save a copy in Drive to keep your changes.
Continue with NumPy tutorials, Generator and reproducibility, random_sample(), randint() and randn(). Reference: NumPy rand documentation.
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.