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

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: 2

Expected 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.

TaskCode
Join along an axisnp.concatenate([a, b], axis=0)
Stack verticallynp.vstack([a, b])
Stack horizontallynp.hstack([a, b])
Add a new axis / split into Nnp.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

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.