Module 2 · Lesson 5
np.newaxis and ... (Ellipsis)
np.newaxis (an alias for None) inserts a new length-1 axis at the
position you place it — the standard way to turn a 1-D array into an
explicit row or column vector, which matters a lot once you start
broadcasting (Module 3). ... (Ellipsis) means “as many full slices : as
needed to cover the remaining axes” — handy for indexing deep into a
high-dimensional array without writing a : for every axis in between.
v = np.array([1, 2, 3])
print(v.shape) # (3,)
print(v[:, np.newaxis].shape) # (3, 1) -- column vector
print(v[np.newaxis, :].shape) # (1, 3) -- row vector
cube = np.arange(24).reshape(2, 3, 4)
print(cube[..., 0].shape) # same as cube[:, :, 0] -> (2, 3)
print(cube[0, ...].shape) # same as cube[0, :, :] -> (3, 4)
grid = np.zeros((3, 3))
grid[1, :] = [7, 8, 9] # assign into a slice
print(grid)
Output:
(3,)
(3, 1)
(1, 3)
(2, 3)
(3, 4)
[[0. 0. 0.]
[7. 8. 9.]
[0. 0. 0.]]
To column vector
Write to_column(v) that takes a 1-D array of shape (n,) and returns it
reshaped to a column vector of shape (n, 1) using np.newaxis (not
.reshape).
💡 Hint
v[:, np.newaxis] adds a new axis at position 1.
✅ Solution
def to_column(v):
return v[:, np.newaxis]
First channel of any stack of images
Write first_channel(images) that takes an array of shape
(n_images, height, width, n_channels) (or any number of leading axes
followed by a channel axis last) and returns just channel 0 for every
image, using ... so your function works regardless of how many
leading axes there are.
💡 Hint
images[..., 0] takes channel 0 regardless of how many axes come before it.
✅ Solution
def first_channel(images):
return images[..., 0]
🎯 Key Takeaways
- Index one axis at a time with
arr[rows, cols]; negative indices and step slices (::2,::-1) work on every axis. - Boolean masks (
arr > 0) filter data; combine conditions with&/|/~, never Python’sand/or/not.np.whereis the vectorized if/else. - Fancy indexing (
arr[[0, 2, 4]]) lets you pick, repeat, and reorder elements arbitrarily — and always returns a copy. - Basic slicing returns a view; boolean and fancy indexing return a
copy. Mutating a view mutates the original array. Use
.copy()when you need independence, andnp.shares_memoryto check. np.newaxisinserts a length-1 axis (crucial for broadcasting);...stands in for “all the remaining axes.”
Next up: Module 3 — Array Operations & Broadcasting, where the shapes you’ve been building here start combining with each other automatically.