Joining and Splitting Arrays: concatenate, stack, split
Data often arrives in pieces: one file per month, one array per branch. NumPy can join pieces into one array and split one array into pieces. The key question is always: along which axis?
- concatenate joins along an axis that already exists: the result has the same number of dimensions.
- stack joins along a new axis: the result has one more dimension.
How to run the examples
Create a new file named join_and_split.py in your NumpyTutorials folder (see the setup in lesson 01). Any name works; this one just matches the topic. Start the file with these lines:
import numpy as np
Then copy the examples of this page into the same file, one after another, in the order shown, and run it with python join_and_split.py (with your virtual environment active). Some examples use variables created in earlier ones, so keep everything in the one file. Each Output box shows what that example prints.
1. concatenate 1D arrays
jan = np.array([10, 20, 30])
feb = np.array([40, 50])
mar = np.array([60])
print("concatenate:", np.concatenate([jan, feb, mar]))
The arrays go in a list (note the square brackets), and they can have different lengths.
2. concatenate 2D arrays: axis=0 and axis=1
store_a = np.array([[1, 2, 3],
[4, 5, 6]])
store_b = np.array([[7, 8, 9]])
print("axis=0 (add rows):\n", np.concatenate([store_a, store_b], axis=0))
extra_column = np.array([[100],
[200]])
print("axis=1 (add columns):\n", np.concatenate([store_a, extra_column], axis=1))
try:
np.concatenate([store_a, store_b], axis=1) # 2 rows vs 1 row
except ValueError as error:
print("Error:", error)
axis=0joins vertically: the rows ofstore_bare added understore_a. The number of columns must match (3 and 3).axis=1joins horizontally: columns are added on the right. The number of rows must match (2 and 2).store_ahas 2 rows andstore_bhas 1, so joining them side by side fails.
Rule: all sizes must be equal except along the axis you join on.
3. vstack, hstack, column_stack
These are shortcuts with easy names, and they also handle 1D arrays nicely:
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print("vstack([a, b]):\n", np.vstack([a, b])) # 1D arrays become rows
print("hstack([a, b]):", np.hstack([a, b])) # one long row
print("column_stack([a, b]):\n", np.column_stack([a, b])) # 1D arrays become columns
| Function | Does | Two 1D arrays of 3 give |
|---|---|---|
np.vstack | stacks vertically (as rows) | shape (2, 3) |
np.hstack | stacks horizontally | shape (6,) |
np.column_stack | uses each 1D array as a column | shape (3, 2) |
4. stack vs concatenate
print("concatenate([a, b]) shape:", np.concatenate([a, b]).shape)
print("stack([a, b]) shape :", np.stack([a, b]).shape, "\n", np.stack([a, b]))
print("stack([a, b], axis=1) shape:", np.stack([a, b], axis=1).shape, "\n", np.stack([a, b], axis=1))
week1 = np.array([[1, 2], [3, 4]])
week2 = np.array([[5, 6], [7, 8]])
print("stack of two 2x2 tables shape:", np.stack([week1, week2]).shape)
concatenateof two(3,)arrays gives(6,): still 1D.stackof two(3,)arrays gives(2, 3): a new first axis, "which array".stack(..., axis=1)puts the new axis second:(3, 2).- Two 2x2 tables stacked give a 3D array
(2, 2, 2), for example "week x row x column".
stack needs all arrays to have exactly the same shape.
5. split and array_split
days = np.arange(1, 13)
print("split into 3 equal parts:", np.split(days, 3))
print("split at indexes [2, 5] :", np.split(days, [2, 5])) # [:2], [2:5], [5:]
try:
np.split(days, 5) # 12 cannot be divided into 5 equal parts
except ValueError as error:
print("Error:", error)
print("array_split into 5 parts :", np.array_split(days, 5))
np.split(days, 3)cuts 12 values into 3 equal parts of 4.np.split(days, [2, 5])cuts at positions 2 and 5:[:2],[2:5],[5:].- 12 values cannot be split into 5 equal parts, so
splitraises an error. np.array_splitallows unequal parts: the first parts get one extra value.
The result is a Python list of arrays, so you can loop over it or unpack it: a, b, c = np.split(days, 3).
6. vsplit and hsplit
table = np.arange(1, 17).reshape(4, 4)
print("table:\n", table)
top, bottom = np.vsplit(table, 2) # split the rows
print("vsplit top:\n", top)
print("vsplit bottom:\n", bottom)
left, right = np.hsplit(table, [1]) # split the columns at column 1
print("hsplit left (first column):\n", left)
print("hsplit right shape:", right.shape)
vsplitsplits the rows (a horizontal cut): top half and bottom half.hsplitsplits the columns (a vertical cut). Here[1]cuts after the first column.
7. Real example: combine branch reports, split into quarters
pune = np.array([120, 130, 125, 140, 150, 160, 170, 165, 180, 190, 200, 210])
mumbai = np.array([220, 210, 230, 240, 250, 245, 260, 270, 280, 300, 310, 320])
report = np.vstack([pune, mumbai]) # 2 branches x 12 months
print("report shape:", report.shape)
q1, q2, q3, q4 = np.hsplit(report, 4) # 4 parts of 3 months
for name, quarter in zip(["Q1", "Q2", "Q3", "Q4"], [q1, q2, q3, q4]):
print(f"{name} totals (Pune, Mumbai):", quarter.sum(axis=1))
with_total = np.column_stack([report, report.sum(axis=1)]) # add a total column
print("last 3 months + yearly total:\n", with_total[:, -4:])
vstackputs the two branches' 12-month rows into one 2x12 report.hsplit(report, 4)cuts the 12 months into 4 quarters of 3 columns each, and we unpack them intoq1toq4.column_stackadds a "yearly total" column on the right.
Exercises
Try these exercises on your own before moving on:
- Join np.zeros(3) and np.ones(2) into one array of 5 values.
- Put three 1D arrays of 4 values on top of each other (shape 3x4) with vstack, and next to each other (shape 4x3) with column_stack.
- Split np.arange(20) into parts of 5 and print the sum of each part.
- Split a 6x4 array into 3 row blocks with vsplit.
Summary
np.concatenate([a, b], axis=...)joins along an existing axis; other sizes must match.vstack(rows),hstack(side by side) andcolumn_stack(1D arrays as columns) are handy shortcuts.np.stackadds a new axis; all arrays must have the same shape.np.splitneeds equal parts or cut positions;np.array_splitallows unequal parts.vsplitcuts rows,hsplitcuts columns; all split functions return a list.