Reshape & Transpose
Reshaping turns one array shape into another without copying data when possible. reshape, ravel, transpose, squeeze, expand_dims — the daily toolkit for getting tensors into the shape a function expects.
reshape, ravel, transpose, broadcast
EXAMPLE
import numpy as np
# 1) Reshape — total element count must match
a = np.arange(12) # shape (12,)
a.reshape(3, 4) # shape (3, 4)
a.reshape(2, 2, 3) # shape (2, 2, 3)
a.reshape(-1, 4) # -1 means 'infer this dim' → (3, 4)
# 2) reshape returns a VIEW when possible (no copy)
b = a.reshape(3, 4)
b[0, 0] = 99
print(a[0]) # 99 — same memory
# Force copy
c = a.reshape(3, 4).copy()
# 3) ravel / flatten — back to 1-D
m = np.array([[1, 2], [3, 4]])
m.ravel() # [1 2 3 4] view
m.flatten() # [1 2 3 4] always a copy
# 4) Transpose — swap axes (view, no data move)
x = np.arange(6).reshape(2, 3) # (2, 3)
x.T # (3, 2)
x.transpose() # same
# 3-D — reorder axes
img = np.zeros((100, 200, 3)) # H, W, C (RGB)
chw = img.transpose(2, 0, 1) # C, H, W (PyTorch format)
# 5) Add / remove unit dimensions
v = np.array([1, 2, 3]) # (3,)
v[:, None] # (3, 1) column vector
v[None, :] # (1, 3) row vector
np.expand_dims(v, 0) # (1, 3)
v.reshape(1, 3, 1).squeeze() # (3,) drops all unit dims
# 6) Broadcasting + reshape together
rows = np.arange(3)[:, None] # (3, 1)
cols = np.arange(4)[None, :] # (1, 4)
grid = rows + cols # (3, 4) outer-product-like
# 7) Stacking — create a new axis
stack = np.stack([np.eye(3), np.eye(3) * 2]) # (2, 3, 3)
# Concatenate along existing axis
np.concatenate([np.zeros((2, 3)), np.ones((2, 3))], axis=0) # (4, 3)
np.concatenate([np.zeros((2, 3)), np.ones((2, 3))], axis=1) # (2, 6)
# 8) Splitting
big = np.arange(24).reshape(4, 6)
np.split(big, 2, axis=1) # two (4, 3) arrays
np.array_split(big, 3, axis=0) # uneven split allowed
# 9) Tile + repeat
np.tile(np.array([1, 2]), 3) # [1 2 1 2 1 2]
np.repeat(np.array([1, 2]), 3) # [1 1 1 2 2 2]
np.tile([[1, 2]], (2, 3)) # (2, 6)
# 10) Pandas — wide ↔ long
import pandas as pd
long = pd.DataFrame({
'date': ['2024-01', '2024-01', '2024-02', '2024-02'],
'product': ['A', 'B', 'A', 'B'],
'sales': [100, 200, 150, 250],
})
# Long → wide
wide = long.pivot(index='date', columns='product', values='sales')
# product A B
# date
# 2024-01 100 200
# 2024-02 150 250
# Wide → long
wide.reset_index().melt(id_vars='date', var_name='product', value_name='sales')
# Pivot with aggregation (handles duplicates)
long.pivot_table(index='date', columns='product', values='sales', aggfunc='sum')
# 11) Stack / unstack — MultiIndex reshape
stacked = wide.stack() # columns → inner index level
stacked.unstack() # back to wide
# 12) Common bugs
# • reshape((-1,)) returns view; modifying it changes original
# • transpose doesn't copy — np.ascontiguousarray() if C order needed
# • PIL/OpenCV use H×W×C; PyTorch uses C×H×W — transpose between them
# • pivot fails on duplicate (index, columns) pairs → use pivot_table
# • np.newaxis is the same as None — both add a length-1 dimension
# • Forgetting axis= in concatenate → uses 0 → wrong shape silently
Why it matters
Most ML bugs are shape bugs. Print .shape at every step until the pipeline is stable, and prefer reshape(-1, N) with one inferred dimension over hard-coded sizes that break when batch size changes.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
import numpy as np a = np.arange(12) print(a.reshape(3, 4)) print(a.reshape(2, -1)) # -1 infers the size print(a.reshape(3, 4).T) # transposeTry it Yourself »
Exercise
Reshape to a 3x4 matrix.
a.
(3, 4)
Seven letters.
Discussion
Loading…