NumPy linspace(): Sample Counts, Endpoints and Practical Grids

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.

ParameterMeaning
start, stopScalar or compatible array-like endpoints
num=50Nonnegative integer sample count
endpoint=TrueInclude stop; False excludes it and changes spacing
retstep=FalseTrue returns (samples, step)
dtype=NoneOutput dtype; inferred real output is floating, not integer
axis=0Position of the new sample axis for array endpoints
device=NoneKeyword-only; explicit cpu available from NumPy 2.0

Default num Creates 50 Samples

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] == 10

Expected 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: 49

Choose Five Samples, Not Five Intervals

With 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 == 6

Expected output

Five samples: [ 2.  4.  6.  8. 10.]
Five intervals: [ 2.   3.6  5.2  6.8  8.4 10. ]

endpoint=False Changes the Spacing

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] < 10

Expected output

Included: [ 2.  4.  6.  8. 10.]
Excluded: [2.  3.6 5.2 6.8 8.4]

retstep Returns Samples and Their Spacing

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.6

Descending and Constant Sequences Are Valid

If 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 == -2

Expected output

Descending: [10.  8.  6.  4.  2.] step: -2.0
Constant: [3. 3. 3. 3.]

Zero and One Samples: Handle the Edge Cases

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 TypeError

Set dtype Explicitly When Needed

Use 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.]

Integer dtype Floors Values and Can Break Equal Spacing

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]

Array Endpoints: axis Controls the Sample Axis

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.]]

Each Endpoint Pair Has Its Own Step

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.]

linspace Uses Count; arange Uses Step

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]

Floating Grids Need Tolerance Checks

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]

Practical Time Grid: Distinguish Duration from Sample Rate

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.1

Periodic Phase: Avoid a Duplicate Endpoint

For 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]

Practical Parameter Sweep with a Stated Toy Model

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.]]

Common linspace Mistakes

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.

Exercise: Two Channels with Five Included Samples

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].

Exercise Solution

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 ]

Practice in Google Colab

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.




Subscribe to our YouTube Channel here



plus2net.com







Python Video Tutorials
Python SQLite Video Tutorials
Python MySQL Video Tutorials
Python Tkinter Video Tutorials
✖
We use cookies to improve your browsing experience. . Learn more
HTML MySQL PHP JavaScript ASP Photoshop Articles Contact us
© 2000-2026 plus2net.com All rights reserved worldwide Privacy Policy Disclaimer