Array Reshaping and Stacking
Reshaping reorganizes the same underlying data into a different shape, as long as the total element count stays the same. arr.reshape(2, 6) and arr.reshape(3, 4) both work on a 12-element array, but arr.reshape(5, 3) fails because 5*3 = 15 doesn't match 12 elements. Stacking functions like np.vstack, np.hstack, and np.concatenate combine multiple arrays into one, while np.split and its variants divide a single array into several.
Cricket analogy: A season's 12 innings scores can be reshaped into a (2, 6) grid of two halves of six matches each, or a (3, 4) grid of quarters, but reshape(5, 3) fails since 15 doesn't match 12; np.hstack can join two teams' scorecards side by side.
reshape, ravel, and flatten
reshape() returns a view when possible (i.e. when the requested shape is compatible with the array's existing memory layout), and a copy otherwise. ravel() flattens an array to 1-D and, like reshape, prefers to return a view. flatten() also flattens to 1-D but always returns a copy, which is the safer (if slightly slower) choice when you need to guarantee the original stays untouched. Passing -1 as one dimension in reshape tells NumPy to infer that dimension's size automatically from the total element count.
Cricket analogy: reshape() on a scorecard array returns a view when the memory layout allows it, ravel() flattening the innings-by-over grid back to one dimension also prefers a view, while flatten() always copies for safety when you need the original untouched, and reshape(-1) lets pandas infer the over count.
Stacking and Concatenation
np.concatenate([a, b], axis=0) joins arrays along an existing axis and requires all other dimensions to match. np.vstack stacks arrays row-wise (equivalent to concatenate along axis=0 after ensuring 2-D), and np.hstack stacks column-wise (axis=1 for 2-D arrays). np.stack, by contrast, joins arrays along a brand-new axis, increasing dimensionality — e.g. stacking three (4,) arrays with np.stack produces a (3, 4) array, whereas concatenating them along axis=0 produces a flat (12,) array.
Cricket analogy: np.concatenate joins two teams' scorecards along an existing axis, np.vstack stacks two innings row-wise into a taller table, np.hstack stacks two overs side by side, while np.stack combining three players' arrays creates a brand-new (3, N) axis instead of one flat array.
import numpy as np
arr = np.arange(12) # shape (12,)
reshaped = arr.reshape(3, 4) # view, shape (3,4)
inferred = arr.reshape(2, -1) # shape (2,6) -- -1 infers 6
# ravel vs flatten
flat_view = reshaped.ravel() # view when possible
flat_copy = reshaped.flatten() # always a copy
# Stacking
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
stacked = np.stack([a, b]) # new axis -> shape (2, 3)
concatenated = np.concatenate([a, b]) # same axis -> shape (6,)
v_stacked = np.vstack([a, b]) # shape (2, 3), rows stacked
h_stacked = np.hstack([a, b]) # shape (6,), columns stacked
# Splitting
split_parts = np.split(np.arange(9), 3) # [array([0,1,2]), array([3,4,5]), array([6,7,8])]A quick way to remember the difference: np.stack always adds a new dimension (like laying sheets of paper on top of each other into a stack), while np.concatenate joins along an existing dimension (like taping sheets edge-to-edge into one longer sheet).
reshape() raises a ValueError if the requested shape's total element count doesn't match the original array's size -- there is no implicit padding or truncation, unlike some other languages' reshape semantics.
- reshape() preserves total element count and returns a view when the new shape is memory-compatible.
- ravel() flattens to 1-D and prefers a view; flatten() flattens to 1-D but always copies.
- Passing -1 as a reshape dimension tells NumPy to infer that size automatically.
- np.concatenate joins arrays along an existing axis; np.stack creates a new axis, increasing dimensionality.
- np.vstack and np.hstack are convenience wrappers for row-wise and column-wise concatenation.
- np.split divides an array into equal (or specified) parts along a given axis.
Practice what you learned
1. What is the key difference between np.stack and np.concatenate?
2. What does passing -1 as a dimension to reshape() do?
3. What is guaranteed about the return value of flatten(), unlike ravel()?
4. Why does arr.reshape(5, 3) fail on a 12-element array?
5. What is np.vstack equivalent to for two 2-D arrays with matching column counts?
Was this page helpful?
You May Also Like
The ndarray: NumPy Basics
The ndarray is NumPy's core data structure — understanding its shape, dtype, strides, and axis conventions is essential to using arrays correctly and efficiently.
Vectorized Operations and Broadcasting
Vectorization applies operations across whole arrays without explicit loops, and broadcasting extends this to arrays of different but compatible shapes.
Concatenating DataFrames
Using pandas' concat function to stack DataFrames or Series along rows or columns, and how it differs from merge in purpose and alignment behavior.
Array Indexing and Slicing
NumPy supports basic slicing, fancy (array) indexing, and boolean masking, each with distinct rules about whether the result is a view or a copy.