Python NumPy: How to Generate Random Numbers from the Uniform Distribution Using NumPy
A uniform distribution is one where every value within a specified range has an equal probability of being selected. This makes it ideal for simulations, random sampling, initializing weights in machine learning models, and generating test data.
NumPy's numpy.random.uniform() function provides a fast and flexible way to generate random numbers from a uniform distribution over any range you specify.
Basic Usage
The simplest call generates a single random float between 0.0 and 1.0:
import numpy as np
value = np.random.uniform()
print(value)
Output (varies each run):
0.17507289334250875
Each time you run this code, you'll get a different number in the range [0.0, 1.0).
Syntax and Parameters
numpy.random.uniform(low=0.0, high=1.0, size=None)
| Parameter | Type | Default | Description |
|---|---|---|---|
low | float | 0.0 | Lower bound of the range (inclusive) |
high | float | 1.0 | Upper bound of the range (exclusive) |
size | int or tuple | None | Shape of the output. None returns a single value |
Returns: A single float (if size=None) or a NumPy array of random samples drawn from the uniform distribution over [low, high).
The range is half-open: it includes low but excludes high. So np.random.uniform(0, 10) can return 0.0 but will never return exactly 10.0.
Generating Arrays of Random Numbers
1D Array
Generate multiple random numbers at once by specifying the size parameter:
import numpy as np
arr = np.random.uniform(size=5)
print(arr)
Output:
[0.70842686 0.29977248 0.12055967 0.09108877 0.42567954]
Custom Range
Specify low and high to generate numbers within any range:
import numpy as np
# Random numbers between 10 and 20
arr = np.random.uniform(low=10, high=20, size=5)
print(arr)
Output:
[17.55213272 18.41387576 14.23431309 13.17861793 10.25633726]
2D Array (Matrix)
Pass a tuple to size to generate multi-dimensional arrays:
import numpy as np
# 3 rows × 4 columns of random numbers between 0 and 100
matrix = np.random.uniform(low=0, high=100, size=(3, 4))
print(matrix)
Output:
[[67.68822006 31.32003778 42.83792523 95.32575867]
[ 7.87682172 9.7836856 52.25497162 0.92994209]
[44.78568788 54.84851153 69.46973075 89.51851093]]
3D Array
Higher dimensions work the same way:
import numpy as np
# 2 layers × 3 rows × 4 columns
arr_3d = np.random.uniform(low=0, high=1, size=(2, 3, 4))
print("Shape:", arr_3d.shape)
print(arr_3d)
Output:
Shape: (2, 3, 4)
[[[0.90694299 0.76646641 0.69752818 0.15469134]
[0.41067961 0.5732826 0.47876719 0.41208416]
[0.45467542 0.78473023 0.16863698 0.08505601]]
[[0.71173349 0.70598537 0.06094019 0.05809846]
[0.99223725 0.41767531 0.2424995 0.16072914]
[0.69372163 0.86707562 0.06119466 0.97138847]]]
Reproducible Results with Random Seeds
For reproducible results (important in testing, debugging, and scientific experiments), set a random seed before generating numbers:
import numpy as np
np.random.seed(42)
print(np.random.uniform(0, 10, size=5))
# Running again with the same seed produces identical output
np.random.seed(42)
print(np.random.uniform(0, 10, size=5))
Output:
[3.74540119 9.50714306 7.31993942 5.98658484 1.5601864 ]
[3.74540119 9.50714306 7.31993942 5.98658484 1.5601864 ]
np.random.default_rng() for modern codeNumPy's newer Generator API (introduced in NumPy 1.17) is recommended over the legacy np.random functions:
import numpy as np
rng = np.random.default_rng(seed=42)
arr = rng.uniform(low=0, high=10, size=5)
print(arr)
Output:
[7.73956049 4.3887844 8.5859792 6.97368029 0.94177348]
The Generator API provides better statistical properties and is thread-safe.
Practical Examples
Simulating Dice Rolls (Continuous)
Generate continuous values that simulate measurements with uniform uncertainty:
import numpy as np
# Simulate 10 measurements between 98.0 and 102.0
measurements = np.random.uniform(low=98.0, high=102.0, size=10)
print("Measurements:", np.round(measurements, 2))
print("Mean:", round(np.mean(measurements), 2))
Output:
Measurements: [ 99.97 101.41 100.12 101.58 99.91 99.48 99.17 101.14 100.97 101.64]
Mean: 100.54
Generating Random Coordinates
import numpy as np
# Generate 5 random (x, y) points in a 100×100 grid
x = np.random.uniform(0, 100, size=5)
y = np.random.uniform(0, 100, size=5)
for i in range(5):
print(f"Point {i+1}: ({x[i]:.1f}, {y[i]:.1f})")
Output:
Point 1: (1.4, 16.5)
Point 2: (80.5, 45.0)
Point 3: (30.1, 58.2)
Point 4: (99.7, 86.9)
Point 5: (49.6, 2.1)
Visualizing the Uniform Distribution
import numpy as np
# Generate a large sample and verify it's uniform
rng = np.random.default_rng(42)
samples = rng.uniform(low=0, high=10, size=100000)
print(f"Min: {samples.min():.4f}")
print(f"Max: {samples.max():.4f}")
print(f"Mean: {samples.mean():.4f} (expected: 5.0)")
print(f"Std: {samples.std():.4f} (expected: {10 / (12**0.5):.4f})")
Output:
Min: 0.0001
Max: 9.9999
Mean: 5.0062 (expected: 5.0)
Std: 2.8852 (expected: 2.8868)
For a uniform distribution over [a, b):
- Expected mean =
(a + b) / 2 - Expected standard deviation =
(b - a) / √12
Uniform vs Other Distributions
NumPy offers many distribution functions. Here's how uniform compares to other common ones:
| Function | Distribution | Use Case |
|---|---|---|
np.random.uniform() | Uniform | Equal probability across a range |
np.random.normal() | Normal (Gaussian) | Bell-curve shaped data |
np.random.randint() | Discrete uniform | Random integers in a range |
np.random.exponential() | Exponential | Time between events |
np.random.binomial() | Binomial | Success/failure trials |
import numpy as np
# Compare: uniform integers vs continuous uniform
print("Continuous:", np.random.uniform(1, 7, size=5))
print("Discrete: ", np.random.randint(1, 7, size=5))
Output:
Continuous: [6.11285414 3.33523913 5.70146948 6.78861586 6.98537949]
Discrete: [4 5 2 4 3]
Conclusion
numpy.random.uniform() is a versatile function for generating random numbers where every value in the specified range is equally likely.
- Use the
lowandhighparameters to define your range, and thesizeparameter to control the output shape, from single values to multi-dimensional arrays. - For reproducible results, always set a random seed, and consider using the modern
np.random.default_rng()API for new projects.