Arrays in NumPy often arrive as matching blocks, such as monthly rows, feature columns, or batches from separate files. Concatenation joins those blocks along an axis that already exists so later calculations can work with one array.
The selected axis is the dimension that grows. For a two-dimensional array, axis=0 adds rows while preserving the column count, and axis=1 adds columns while preserving the row count.
Dimensions outside the join axis must match exactly for np.concatenate(). np.stack() keeps each input as a separate layer by adding a new axis, while axis=None makes NumPy flatten every input before joining.
Related: Stack arrays
Related: Create an array
Related: Reshape an array
import numpy as np north = np.array([[10, 11, 12], [13, 14, 15]]) south = np.array([[20, 21, 22]]) east = np.array([[30], [31]])
south has the same three-column width as north, while east has the same two-row height.
by_row = np.concatenate((north, south), axis=0) expected_by_row = np.array([[10, 11, 12], [13, 14, 15], [20, 21, 22]]) np.testing.assert_array_equal(by_row, expected_by_row)
axis=0 grows the first dimension from two rows to three while retaining all three columns.
by_column = np.concatenate((north, east), axis=1) expected_by_column = np.array([[10, 11, 12, 30], [13, 14, 15, 31]]) np.testing.assert_array_equal(by_column, expected_by_column)
axis=1 grows the second dimension from three columns to four while retaining both rows.
print("north shape:", north.shape) print("south shape:", south.shape) print("east shape:", east.shape) print("by row:") for row in by_row: print(" ", row.tolist()) print("by row shape:", by_row.shape) print("by column:") for row in by_column: print(" ", row.tolist()) print("by column shape:", by_column.shape)
import numpy as np north = np.array([[10, 11, 12], [13, 14, 15]]) south = np.array([[20, 21, 22]]) east = np.array([[30], [31]]) by_row = np.concatenate((north, south), axis=0) expected_by_row = np.array([[10, 11, 12], [13, 14, 15], [20, 21, 22]]) np.testing.assert_array_equal(by_row, expected_by_row) by_column = np.concatenate((north, east), axis=1) expected_by_column = np.array([[10, 11, 12, 30], [13, 14, 15, 31]]) np.testing.assert_array_equal(by_column, expected_by_column) print("north shape:", north.shape) print("south shape:", south.shape) print("east shape:", east.shape) print("by row:") for row in by_row: print(" ", row.tolist()) print("by row shape:", by_row.shape) print("by column:") for row in by_column: print(" ", row.tolist()) print("by column shape:", by_column.shape)
$ python3 array-concatenate.py north shape: (2, 3) south shape: (1, 3) east shape: (2, 1) by row: [10, 11, 12] [13, 14, 15] [20, 21, 22] by row shape: (3, 3) by column: [10, 11, 12, 30] [13, 14, 15, 31] by column shape: (2, 4)
The output keeps rank 2 in both joins. The row join becomes (3, 3), and the column join becomes (2, 4).