np.linspace() creates a chosen number of evenly spaced samples between start and stop. It includes both endpoints by default. Use it when sample count matters, and choose the endpoint policy before calculating the spacing.
| Parameter | Meaning |
|---|---|
start, stop | Scalar or compatible array-like endpoints |
num=50 | Nonnegative integer sample count |
endpoint=True | Include stop; False excludes it and changes spacing |
retstep=False | True returns (samples, step) |
dtype=None | Output dtype; inferred real output is floating, not integer |
axis=0 | Position of the new sample axis for array endpoints |
device=None | Keyword-only; explicit cpu available from NumPy 2.0 |
linspace takes a sample count, not a step size. The default num is 50, including both endpoints. There are 49 gaps between 50 samples. Default dtype is floating for real numeric endpoints, even if the inputs are integers.
import numpy as np
a = np.linspace(2, 10)
print(a)
print("Samples:", a.size)
print("Gaps:", a.size - 1)
assert a.size == 50 and a[0] == 2 and a[-1] == 10Expected output
[ 2. 2.16326531 2.32653061 2.48979592 2.65306122 2.81632653
2.97959184 3.14285714 3.30612245 3.46938776 3.63265306 3.79591837
3.95918367 4.12244898 4.28571429 4.44897959 4.6122449 4.7755102
4.93877551 5.10204082 5.26530612 5.42857143 5.59183673 5.75510204
5.91836735 6.08163265 6.24489796 6.40816327 6.57142857 6.73469388
6.89795918 7.06122449 7.2244898 7.3877551 7.55102041 7.71428571
7.87755102 8.04081633 8.20408163 8.36734694 8.53061224 8.69387755
8.85714286 9.02040816 9.18367347 9.34693878 9.51020408 9.67346939
9.83673469 10. ]
Samples: 50
Gaps: 49With endpoint=True and num greater than one, spacing is (stop-start)/(num-1). To obtain five equal intervals including both ends, request six samples.
samples = np.linspace(2, 10, 5)
five_intervals = np.linspace(2, 10, 6)
print("Five samples:", samples)
print("Five intervals:", five_intervals)
np.testing.assert_array_equal(samples, [2, 4, 6, 8, 10])
assert five_intervals.size == 6Expected output
Five samples: [ 2. 4. 6. 8. 10.]
Five intervals: [ 2. 3.6 5.2 6.8 8.4 10. ]Excluding stop still returns num samples. For num greater than zero, spacing becomes (stop-start)/num. It is not the same as dropping the last value from the endpoint=True result with the same num.
included = np.linspace(2, 10, 5)
excluded = np.linspace(2, 10, 5, endpoint=False)
print("Included:", included)
print("Excluded:", excluded)
np.testing.assert_allclose(excluded, [2, 3.6, 5.2, 6.8, 8.4])
assert excluded.size == included.size == 5
assert excluded[-1] < 10Expected output
Included: [ 2. 4. 6. 8. 10.]
Excluded: [2. 3.6 5.2 6.8 8.4]Unpack the (samples, step) tuple for readable code. Floating-point step comparisons should use tolerances. For multiple endpoint arrays, step can itself be an array.
samples, step = np.linspace(2, 10, 5, retstep=True)
print("Samples:", samples)
print("Step:", step)
excluded, other_step = np.linspace(2, 10, 5, endpoint=False, retstep=True)
print("Excluded-endpoint step:", other_step)
np.testing.assert_allclose(np.diff(samples), step)
assert step == 2
np.testing.assert_allclose(other_step, 1.6)Expected output
Samples: [ 2. 4. 6. 8. 10.]
Step: 2.0
Excluded-endpoint step: 1.6If stop is below start, the spacing is negative. Equal endpoints produce repeated values. A descending grid is valid, but later calculations must know its order.
descending, step = np.linspace(10, 2, 5, retstep=True)
constant = np.linspace(3, 3, 4)
print("Descending:", descending, "step:", step)
print("Constant:", constant)
np.testing.assert_array_equal(descending, [10, 8, 6, 4, 2])
assert step == -2Expected output
Descending: [10. 8. 6. 4. 2.] step: -2.0
Constant: [3. 3. 3. 3.]num=0 returns an empty array. num=1 returns start, even with endpoint=True. With an included endpoint and fewer than two samples, retstep is NaN because no spacing can be defined. Negative or non-integer num is invalid.
for count in [0, 1]:
a, step = np.linspace(2, 10, count, retstep=True)
print("num:", count, "samples:", a, "step:", step)
assert a.size == count and np.isnan(step)
one, step = np.linspace(2, 10, 1, endpoint=False, retstep=True)
print("One excluded-endpoint sample:", one, "step:", step)
assert one[0] == 2 and step == 8
for count in [-1, 2.5]:
try:
np.linspace(2, 10, count)
except (ValueError, TypeError) as error:
print("Rejected:", count, type(error).__name__)
else:
raise AssertionError('Expected invalid num')Expected output
num: 0 samples: [] step: nan
num: 1 samples: [2.] step: nan
One excluded-endpoint sample: [2.] step: 8.0
Rejected: -1 ValueError
Rejected: 2.5 TypeErrorUse float64 for ordinary numeric grids or another supported type when the next operation requires it. The original integer examples work because their generated values are already whole numbers. See dtype.
for dtype in [np.int8, np.int32, np.float64]:
a = np.linspace(2, 10, 5, dtype=dtype)
print(dtype.__name__, a)
np.testing.assert_array_equal(a, [2, 4, 6, 8, 10])Expected output
int8 [ 2 4 6 8 10]
int32 [ 2 4 6 8 10]
float64 [ 2. 4. 6. 8. 10.]Since NumPy 1.20, explicit integer dtype rounds toward negative infinity. This differs from generating floats then casting to integers, which truncates toward zero. Integer conversion can duplicate points or create unequal gaps; keep a float grid when even spacing matters.
floating = np.linspace(-1, 1, 5)
integer = np.linspace(-1, 1, 5, dtype=np.int32)
cast = floating.astype(np.int32)
print("Float grid:", floating)
print("Integer dtype:", integer)
print("Later integer cast:", cast)
np.testing.assert_array_equal(integer, [-1, -1, 0, 0, 1])
np.testing.assert_array_equal(cast, [-1, 0, 0, 0, 1])Expected output
Float grid: [-1. -0.5 0. 0.5 1. ]
Integer dtype: [-1 -1 0 0 1]
Later integer cast: [-1 0 0 0 1]For two start/stop pairs and five samples, axis=0 gives shape (5, 2); axis=1 gives (2, 5). Samples run down rows or across columns respectively. This axis inserts the sample dimension rather than reducing an existing one. See shape.
start = np.array([2, 5])
stop = np.array([6, 25])
rows = np.linspace(start, stop, 5, axis=0)
columns = np.linspace(start, stop, 5, axis=1)
print("Samples in rows:")
print(rows)
print("Samples in columns:")
print(columns)
assert rows.shape == (5, 2) and columns.shape == (2, 5)
np.testing.assert_array_equal(rows.T, columns)Expected output
Samples in rows:
[[ 2. 5.]
[ 3. 10.]
[ 4. 15.]
[ 5. 20.]
[ 6. 25.]]
Samples in columns:
[[ 2. 3. 4. 5. 6.]
[ 5. 10. 15. 20. 25.]]The endpoint arrays can specify multiple ranges sampled together. The sample count is shared, while retstep describes the spacing for each range.
samples, steps = np.linspace([2, 5], [6, 25], 5, axis=-1, retstep=True)
print("Samples:")
print(samples)
print("Steps:", steps)
np.testing.assert_array_equal(steps, [1, 5])
np.testing.assert_allclose(np.diff(samples, axis=-1), np.broadcast_to(steps[:, None], (2, 4)))Expected output
Samples:
[[ 2. 3. 4. 5. 6.]
[ 5. 10. 15. 20. 25.]]
Steps: [1. 5.]Choose linspace when the number of samples and endpoint policy matter. Choose arange() when a step is the input. With floating steps, avoid relying on arange to deliver a particular endpoint or count because representation errors can affect the result.
by_count = np.linspace(2, 10, 5)
by_step = np.arange(2, 11, 2)
print("By count:", by_count)
print("By integer step:", by_step)
np.testing.assert_array_equal(by_count, by_step)
print("Ten fractional steps, excluded endpoint:", np.linspace(0, 1, 10, endpoint=False))Expected output
By count: [ 2. 4. 6. 8. 10.]
By integer step: [ 2 4 6 8 10]
Ten fractional steps, excluded endpoint: [0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]Evenly spaced describes the intended construction, not a guarantee of exact equality of every stored binary difference. Use allclose with tolerances appropriate to the scale instead of testing every difference with ==.
a, step = np.linspace(0, 1, 11, retstep=True)
gaps = np.diff(a)
print("Step:", step)
print("Gaps close to step:", np.allclose(gaps, step))
print("Exact gap equality:", gaps == step)
np.testing.assert_allclose(gaps, step, rtol=1e-12, atol=1e-15)Expected output
Step: 0.1
Gaps close to step: True
Exact gap equality: [ True True False False False False False False False False]For a synthetic two-second interval sampled at 10 samples per second, use 20 points with endpoint=False. Including both ends at spacing 0.1 instead requires 21 points. State whether the final time is included before computing the sample count.
duration = 2.0
rate = 10
time_open, step_open = np.linspace(0, duration, int(duration * rate), endpoint=False, retstep=True)
time_closed, step_closed = np.linspace(0, duration, int(duration * rate) + 1, retstep=True)
print("Half-open count / last:", time_open.size, time_open[-1])
print("Closed count / last:", time_closed.size, time_closed[-1])
print("Steps:", step_open, step_closed)
assert time_open.size == 20 and time_closed.size == 21
np.testing.assert_allclose([step_open, step_closed], [0.1, 0.1])Expected output
Half-open count / last: 20 1.9000000000000001
Closed count / last: 21 2.0
Steps: 0.1 0.1For N phases around a circle, exclude 2*pi because it represents the same direction as zero. A deterministic phase grid is different from random sampling.
phase = np.linspace(0, 2 * np.pi, 8, endpoint=False)
signal = np.sin(phase)
print("Phases:", np.round(phase, 3))
print("Synthetic sine values:", np.round(signal, 3))
assert phase.size == 8 and phase[-1] < 2 * np.pi
np.testing.assert_allclose(signal, [0, np.sqrt(0.5), 1, np.sqrt(0.5), 0, -np.sqrt(0.5), -1, -np.sqrt(0.5)], atol=1e-14)Expected output
Phases: [0. 0.785 1.571 2.356 3.142 3.927 4.712 5.498]
Synthetic sine values: [ 0. 0.707 1. 0.707 0. -0.707 -1. -0.707]This synthetic cost model is cost = 100 + 3*quantity. Use an evenly spaced float grid to inspect the model at eleven planned quantities from zero through 100. These are deterministic evaluation points, not observed sales or random values.
quantity = np.linspace(0, 100, 11)
cost = 100 + 3 * quantity
table = np.column_stack([quantity, cost])
print("Quantity / model cost:")
print(table)
assert table.shape == (11, 2)
np.testing.assert_array_equal(table[[0, -1]], [[0, 100], [100, 400]])Expected output
Quantity / model cost:
[[ 0. 100.]
[ 10. 130.]
[ 20. 160.]
[ 30. 190.]
[ 40. 220.]
[ 50. 250.]
[ 60. 280.]
[ 70. 310.]
[ 80. 340.]
[ 90. 370.]
[100. 400.]]num is a count, not a step or number of intervals. endpoint=False changes spacing. Integer dtype can destroy uniform gaps. retstep returns a tuple rather than only samples. Array endpoint axis controls where samples are inserted. linspace is linear spacing; logspace and geomspace address logarithmic spacing. There is no out argument. NumPy 2.0 added keyword-only device, which accepts explicit "cpu" for this API; ordinary tutorial code can omit it. Avoid excessive sample counts without checking memory requirements.
Create five samples from 0 to 1 for channel A and from 10 to 20 for channel B. Put channels in rows and sample positions in columns. Return the two step values. Predict shape (2, 5), steps [0.25, 2.5] and final values [1, 20].
Use array endpoints and axis=-1 to put the sample axis last. Verify both endpoints and the gaps for each channel.
samples, steps = np.linspace([0, 10], [1, 20], num=5, axis=-1, retstep=True)
print(samples)
print("Steps:", steps)
assert samples.shape == (2, 5)
np.testing.assert_allclose(steps, [0.25, 2.5])
np.testing.assert_allclose(samples[:, 0], [0, 10])
np.testing.assert_allclose(samples[:, -1], [1, 20])
np.testing.assert_allclose(np.diff(samples, axis=1), np.broadcast_to(steps[:, None], (2, 4)))Expected output
[[ 0. 0.25 0.5 0.75 1. ]
[10. 12.5 15. 17.5 20. ]]
Steps: [0.25 2.5 ]Open in Google Colab View on GitHub
All sample data is embedded. Run the examples and practise sample counts, endpoints and channel grids. Save a copy in Drive to keep your changes.
Continue with NumPy tutorials, arange(), advanced array creation, eye(), ones() and bincount(). Reference: NumPy linspace 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.