Skip to main content

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)
ParameterTypeDefaultDescription
lowfloat0.0Lower bound of the range (inclusive)
highfloat1.0Upper bound of the range (exclusive)
sizeint or tupleNoneShape 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).

note

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 ]
Use np.random.default_rng() for modern code

NumPy'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)
note

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:

FunctionDistributionUse Case
np.random.uniform()UniformEqual probability across a range
np.random.normal()Normal (Gaussian)Bell-curve shaped data
np.random.randint()Discrete uniformRandom integers in a range
np.random.exponential()ExponentialTime between events
np.random.binomial()BinomialSuccess/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 low and high parameters to define your range, and the size parameter 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.