Reshaping, stacking & splitting arrays
Data rarely arrives in the shape your calculation needs. Monthly sales might come as one long vector when you want a store x month table, or you might need to join two batches of readings. NumPy gives you precise tools for this.
reshape: same data, new shape
The total number of elements must stay the same. Use -1 to let NumPy work out one dimension:
import numpy as np
sales = np.arange(1, 13) # 12 monthly values
by_quarter = sales.reshape(4, 3) # 4 quarters x 3 months
by_half = sales.reshape(2, -1) # 2 halves x 6 months
print(by_quarter.shape, by_half.shape) # (4, 3) (2, 6)
reshape returns a view when it can, meaning it shares memory with the original. Changing the view changes
the original too. Call .copy() if you need independent data.
Flattening and transposing
| Operation | Result |
|---|---|
a.ravel() |
1-D view when possible |
a.flatten() |
1-D copy, always |
a.T |
Transpose (rows become columns) |
a[:, np.newaxis] |
Adds an axis: shape (n,) to (n, 1) |
np.squeeze(a) |
Removes axes of length 1 |
Adding an axis is common before broadcasting, for example turning a vector of store targets into a column so it lines up with a store x month matrix.
Joining arrays
jan = np.array([120, 95, 143]) # three stores
feb = np.array([130, 88, 150])
np.concatenate([jan, feb]) # shape (6,) - joins along an existing axis
np.stack([jan, feb]) # shape (2, 3) - creates a NEW axis (months x stores)
np.stack([jan, feb], axis=1) # shape (3, 2) - stores x months
np.vstack([jan, feb]) # rows on top of each other: (2, 3)
np.hstack([jan, feb]) # side by side: (6,)
np.column_stack([jan, feb]) # 1-D arrays become columns: (3, 2)
The rule of thumb: concatenate joins along an axis that already exists; stack adds a new one, so all
inputs must have the same shape.
Splitting arrays
year = np.arange(12)
q1, q2, q3, q4 = np.split(year, 4) # four equal parts
parts = np.split(year, [3, 8]) # cut before index 3 and 8
uneven = np.array_split(np.arange(10), 3) # sizes 4, 3, 3 - allowed
np.split raises an error if the array cannot be divided equally; np.array_split allows unequal pieces, which is
handy for creating batches.
For 2-D arrays, np.hsplit splits columns and np.vsplit splits rows.
A realistic example
Daily footfall for four weeks in a Chennai store, reshaped into weeks and summarised:
rng = np.random.default_rng(7)
daily = rng.integers(200, 500, size=28)
weeks = daily.reshape(4, 7) # 4 weeks x 7 days
print(weeks.sum(axis=1)) # weekly totals
print(weeks.mean(axis=0).round(1)) # average by weekday
Common mistakes
- Using
reshapewhen the element count does not match (for example 10 values into(3, 3)). - Confusing
stackandconcatenate, and ending up with the wrong number of dimensions. - Modifying a reshaped view and being surprised the original changed.
- Reshaping row-major data as if it were column-major;
reshapefills rows first by default (order="C").
Practice
Generate 365 daily sales values. Keep the first 364 days and reshape them into 52 weeks x 7 days, find the best
week, then split the year into 4 roughly equal parts with np.array_split and print each part's total.