Same numbers, different axes. reshape fails if the size changes. ravel is usually a view; flatten always copies.
Goal
Turn a 12-vector into months × products, transpose it, and see when ravel shares memory.
reshape
# 4 months × products A, B, C
months = np.arange(12, dtype=float)
grid = months.reshape(4, 3)
print(grid)
print("size:", months.size, "grid size:", grid.size)Size must match
months = np.arange(12)
try:
print(months.reshape(5, 3))
except ValueError as err:
print(err)T and swapaxes
grid = np.arange(12, dtype=float).reshape(4, 3)
print("T:")
print(grid.T)
print("shape:", grid.T.shape)(4, 3) becomes (3, 4) — products × months.
ravel vs flatten
grid = np.arange(12, dtype=float).reshape(4, 3)
flat = grid.ravel()
flat[0] = -1
print("after ravel write:")
print(grid)
print("ravel.base is grid:", flat.base is grid)
print()
copy = grid.flatten()
copy[1] = -2
print("after flatten write, grid[0, 1] still", grid[0, 1])expand_dims
city_totals = np.array([21, 15, 15], dtype=float)
print(city_totals.shape)
col = np.expand_dims(city_totals, axis=1)
print(col.shape)
print(col)Same idea as city_totals[:, np.newaxis] — useful before you divide a grid by row totals.
Pitfall
reshape(-1, 3) infers the first axis. reshape(3) on a 12-vector still fails — 12 is not 3.