Understanding shape
shape tells the size of each dimension.
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.shape) # (2, 3)Reshape with .reshape()
Reshape changes the dimension layout without changing the underlying data or copying it — it just reinterprets the same flat block of memory with a new shape.
import numpy as np
arr = np.arange(1, 13) # 1..12
mat = arr.reshape(3, 4) # 3 rows, 4 cols
print(mat)Using -1 (auto infer)
import numpy as np
arr = np.arange(12)
mat = arr.reshape(3, -1)
print(mat.shape) # (3, 4)Flattening arrays
.ravel() (often a view)
import numpy as np
mat = np.array([[1, 2], [3, 4]])
flat = mat.ravel()
print(flat).flatten() (always copy)
import numpy as np
mat = np.array([[1, 2], [3, 4]])
flat = mat.flatten()
print(flat)Add or remove dimensions
np.newaxis / None
Convert a 1D array into a column vector:
import numpy as np
arr = np.array([1, 2, 3])
col = arr[:, None]
print(col)
print(col.shape) # (3, 1)np.expand_dims
import numpy as np
arr = np.array([1, 2, 3])
arr2 = np.expand_dims(arr, axis=0)
print(arr2.shape) # (1, 3)np.squeeze (remove size-1 dims)
import numpy as np
arr = np.array([[[1], [2], [3]]])
print(arr.shape) # (1, 3, 1)
print(np.squeeze(arr).shape) # (3,)Transpose (swap axes)
Transposing is a special case of reshaping — it also returns a view, never a copy.
For 2D:
import numpy as np
mat = np.array([[1, 2, 3], [4, 5, 6]])
print(mat.T)flowchart LR A["ndarray"] --> B["reshape(r, c)
same data, new grid"] A --> C["ravel() / flatten()
collapse to 1D"] A --> D["expand_dims / newaxis
add a dimension"] A --> E["squeeze()
remove size-1 dims"] A --> F["T / swapaxes()
reorder axes"]
Check your understanding
For arr = np.arange(12), what is arr.reshape(3, -1).shape?
The -1 tells NumPy to infer that axis. 12 elements in 3 rows means 4 columns.
Show answer
B — (3, 4) — The -1 tells NumPy to infer that axis. 12 elements in 3 rows means 4 columns.
What is the difference between ravel() and flatten()?
ravel returns a view when it can, so editing it may change the original. flatten always makes a copy.
Show answer
A — ravel() is often a view while flatten() always returns a copy — ravel returns a view when it can, so editing it may change the original. flatten always makes a copy.
For arr = np.array([1, 2, 3]), what is arr[:, None].shape?
None (np.newaxis) adds an axis, turning the 1D array into a column vector of shape (3, 1). np.expand_dims(arr, axis=0) would give (1, 3).
Show answer
C — (3, 1) — None (np.newaxis) adds an axis, turning the 1D array into a column vector of shape (3, 1). np.expand_dims(arr, axis=0) would give (1, 3).
What is np.squeeze(arr).shape when arr.shape is (1, 3, 1)?
squeeze removes every axis of size 1, leaving just (3,).
Show answer
A — (3,) — squeeze removes every axis of size 1, leaving just (3,).
Next
Continue to: Broadcasting in NumPy to learn how NumPy applies operations between different shapes.
🧪 Try It Yourself
Exercise 1 – Reshape with -1
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.Exercise 2 – Flatten a Matrix
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.Exercise 3 – Column Vector with newaxis
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.