Stacking & Splitting Arrays
Reviewed & published by Brayan K
Stacking and splitting are the NumPy operations that join multiple arrays into one and divide one array back into several — letting you assemble and reshape datasets without manual loops.
Part of the free NumPy course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll combine arrays with concatenate, vstack, hstack, and stack, then break them apart again with split, hsplit, and vsplit, all with clear before-and-after output.
What You'll Learn in This Lesson
- Joining arrays with np.concatenate and axis
- Stacking vertically with np.vstack
- Stacking horizontally with np.hstack
- Adding a new axis with np.stack
- Splitting with np.split
- Row and column splits: vsplit and hsplit
1 Joining with np.concatenate
np.concatenate is the most general join. You give it a list of arrays and an axis, and it glues them together along that existing axis. For 1D arrays there is only one axis, so it simply chains them end to end.
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(np.concatenate([a, b])) # [1 2 3 4 5 6]
# For 2D arrays, choose the axis to join along
m1 = np.array([[1, 2], [3, 4]])
m2 = np.array([[5, 6], [7, 8]])
print(np.concatenate([m1, m2], axis=0)) # stack rows
# [[1 2]
# [3 4]
# [5 6]
# [7 8]]
print(np.concatenate([m1, m2], axis=1)) # stack columns
# [[1 2 5 6]
# [3 4 7 8]]
# ✅ Expected output:
# [1 2 3 4 5 6]
# [[1 2]
# [3 4]
# [5 6]
# [7 8]]
# [[1 2 5 6]
# [3 4 7 8]]2 vstack and hstack Shortcuts
Typing axis every time gets tedious, so NumPy provides two friendly shortcuts. np.vstack stacks arrays vertically (more rows) and np.hstack stacks them horizontally (more columns).
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# Vertical: place b under a -> a 2x3 array
print(np.vstack([a, b]))
# [[1 2 3]
# [4 5 6]]
# Horizontal: lay them end to end -> length 6
print(np.hstack([a, b])) # [1 2 3 4 5 6]
# With 2D arrays, hstack adds columns side by side
left = np.array([[1], [2]])
right = np.array([[3], [4]])
print(np.hstack([left, right]).tolist()) # [[1, 3], [2, 4]]
# ✅ Expected output:
# [[1 2 3]
# [4 5 6]]
# [1 2 3 4 5 6]
# [[1, 3], [2, 4]]Expected output: the 2×3 vertical stack, the length-6 horizontal stack, and the 2×2 column join [[1 3] [2 4]].
3 np.stack Adds a New Axis
Unlike concatenate, np.stack introduces a brand-new dimension. Stacking two length-3 1D arrays produces a 2×3 array — the inputs become rows of a fresh axis, so the result has one more dimension than the inputs.
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# Default axis=0: each array becomes a row
s0 = np.stack([a, b])
print(s0)
# [[1 2 3]
# [4 5 6]]
print(s0.shape) # (2, 3)
# axis=1: pair up element by element into columns
s1 = np.stack([a, b], axis=1)
print(s1)
# [[1 4]
# [2 5]
# [3 6]]
print(s1.shape) # (3, 2)
# ✅ Expected output:
# [[1 2 3]
# [4 5 6]]
# (2, 3)
# [[1 4]
# [2 5]
# [3 6]]
# (3, 2)Expected output: a (2, 3) array stacked along axis 0, and a (3, 2) array along axis 1 pairing one element from each input per row.
4 Splitting Arrays Back Apart
np.split is the inverse of concatenate. Give it an array and the number of equal pieces, and it returns a list of sub-arrays. np.hsplit and np.vsplit are the column and row shortcuts.
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6])
# Split into 3 equal pieces
parts = np.split(arr, 3)
print(parts) # [array([1, 2]), array([3, 4]), array([5, 6])]
# Split at specific indices (before index 2 and before index 5)
print(np.split(arr, [2, 5]))
# [array([1, 2]), array([3, 4, 5]), array([6])]
grid = np.array([[1, 2, 3, 4],
[5, 6, 7, 8]])
# hsplit into 2 -> left columns [[1,2],[5,6]] and right [[3,4],[7,8]]
left_cols, right_cols = np.hsplit(grid, 2)
print(left_cols.tolist()) # [[1, 2], [5, 6]]
# vsplit into 2 -> two single-row blocks
top_row, bottom_row = np.vsplit(grid, 2)
print(bottom_row.tolist()) # [[5, 6, 7, 8]]
# ✅ Expected output:
# [array([1, 2]), array([3, 4]), array([5, 6])]
# [array([1, 2]), array([3, 4, 5]), array([6])]
# [[1, 2], [5, 6]]
# [[5, 6, 7, 8]]🎯 YOUR TURN: Fill in the Blanks
Replace each ___ so the program stacks two rows vertically and then splits them back apart.
import numpy as np
top = np.array([1, 2, 3])
bottom = np.array([4, 5, 6])
# Stack bottom under top into a 2x3 array
combined = np.___([top, bottom]) # fill in the vertical-stack function
# Split the combined array back into 2 row pieces
pieces = np.vsplit(combined, ___) # fill in the number of pieces
print(combined)
# [[1 2 3]
# [4 5 6]]
print(len(pieces)) # Expected output: 2Expected output: the 2×3 array and 2. (Answers: vstack, 2.)
⚠️ Common Errors & Quick Reference
❌ ValueError: all the input array dimensions ... must match
The non-joining dimension differs between the arrays (e.g. different column counts when stacking rows).
✅ Fix: make sure every dimension except the one you join along is equal. Print each .shape to compare.
❌ ValueError: array split does not result in an equal division
np.split with an integer needs the length to divide evenly.
✅ Fix: choose a divisor that fits, or pass a list of split indices instead.
| Task | Code |
|---|---|
| Join along an axis | np.concatenate([a, b], axis=0) |
| Stack vertically | np.vstack([a, b]) |
| Stack horizontally | np.hstack([a, b]) |
| Add a new axis / split into N | np.stack([a, b]) / np.split(arr, N) |
🏆 Mini Challenge: Build and Slice a Table
Combine an IDs column with a scores column side by side, then split the table back into its two columns.
import numpy as np
ids = np.array([[101], [102], [103]])
scores = np.array([[88], [92], [75]])
# Place the two columns side by side -> shape (3, 2)
table = np.hstack([ids, scores])
print(table.tolist()) # [[101, 88], [102, 92], [103, 75]]
# Split back into the two original columns
id_col, score_col = np.hsplit(table, 2)
print(score_col.ravel()) # [88 92 75]
# ✅ Expected output:
# [[101, 88], [102, 92], [103, 75]]
# [88 92 75]❓ Frequently Asked Questions
Lesson complete — you can assemble arrays at will!
You now join arrays with concatenate, vstack, hstack, and stack, and break them apart with split, hsplit, and vsplit.
Practice quiz
What is the key difference between np.concatenate and np.stack?
- concatenate joins along an existing axis; stack adds a new axis
- They are identical
- stack only works on 1D
- concatenate adds a dimension
Answer: concatenate joins along an existing axis; stack adds a new axis. concatenate keeps the number of dimensions; stack introduces a brand-new axis.
What does np.vstack do?
- Sorts arrays
- Stacks arrays vertically, adding rows
- Splits an array
- Adds columns
Answer: Stacks arrays vertically, adding rows. vstack stacks arrays on top of each other, producing more rows.
What does np.hstack do?
- Adds rows
- Transposes
- Stacks arrays horizontally, adding columns
- Removes duplicates
Answer: Stacks arrays horizontally, adding columns. hstack lays arrays side by side, producing more columns.
Stacking two length-3 1D arrays with np.stack gives what shape?
- (6,)
- (3,)
- (1, 6)
- (2, 3)
Answer: (2, 3). stack adds a new axis, turning two 1D arrays into a (2, 3) array.
What does np.concatenate require of the arrays?
- They match in every dimension except the joining axis
- They are identical
- They are 1D only
- They have the same dtype only
Answer: They match in every dimension except the joining axis. Concatenation needs all non-joining dimensions to be equal, else it raises ValueError.
Which axis does np.concatenate use to stack rows on 2D arrays?
- axis=2
- axis=0
- axis=1
- axis=-1
Answer: axis=0. axis=0 joins along rows, placing arrays on top of each other.
What does np.stack([a, b], axis=1) do to two length-3 arrays?
- Concatenates them end to end
- Returns shape (2, 3)
- Pairs elements into columns, giving shape (3, 2)
- Raises an error
Answer: Pairs elements into columns, giving shape (3, 2). axis=1 pairs one element from each input per row, giving (3, 2).
Which is the inverse operation of stacking?
- Sorting
- Reshaping
- Transposing
- Splitting
Answer: Splitting. np.split (and hsplit/vsplit) divides an array back into pieces, the inverse of stacking.
Compared to its inputs, np.stack produces an array with...
- One more dimension
- The same number of dimensions
- One fewer dimension
- Always 1 dimension
Answer: One more dimension. stack adds a new axis, so the result gains one dimension.
np.vstack([a, b]) is a shortcut for which call on 2D arrays?
- np.hstack([a, b])
- np.stack([a, b])
- np.concatenate([a, b], axis=0)
- np.split([a, b])
Answer: np.concatenate([a, b], axis=0). vstack is concatenate with axis=0, stacking arrays vertically.
Continue this course
- Previous: Aggregations: sum, mean, axis
- Next: Copies vs Views — Know when slicing shares memory and when it copies data
- Quick reference: NumPy cheat sheet › Reshaping & Stacking
Frequently asked questions
What is the difference between concatenate and stack?
np.concatenate joins arrays along an existing axis, so the result has the same number of dimensions as the inputs. np.stack joins arrays along a brand-new axis, so the result gains one dimension. Use concatenate to lengthen or widen an array, and stack to layer arrays into a higher-dimensional block.
What do vstack and hstack do?
np.vstack stacks arrays vertically, placing them on top of each other so the result has more rows. np.hstack stacks arrays horizontally, placing them side by side so the result has more columns. They are convenient shortcuts for np.concatenate with axis=0 and axis=1 on 2D arrays.
How do I split an array back into pieces?
Use np.split to divide an array into equal sections along an axis, or the shortcuts np.hsplit (split into columns) and np.vsplit (split into rows). You can pass an integer for the number of equal parts, or a list of indices to cut at specific positions.
Why do I get an error when concatenating arrays?
Concatenation requires the arrays to match in every dimension except the one you are joining along. If the rows you stack have different column counts, or the columns you stack have different row counts, NumPy raises a ValueError. Check that the non-joining dimensions are equal.