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 reshape when the element count does not match (for example 10 values into (3, 3)).
  • Confusing stack and concatenate, 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; reshape fills 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.

B

Written by Bablu Kumar Jha

Founder, BeeProton AI · Mumbai, Maharashtra, India