NumPy
Python
multidimensional arrays
indexing
column access

How do I access the ith column of a NumPy multidimensional array?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Accessing the ith column of a NumPy array is usually one line, but the shape of the result matters. In a two-dimensional array, arr[:, i] gives you the column as a one-dimensional vector, while arr[:, i:i+1] keeps it as a two-dimensional column matrix.

That difference is easy to overlook, and it is one of the main reasons column-selection code later breaks during concatenation, matrix operations, or model input preparation.

Basic Column Access in a 2D Array

For a normal matrix, use:

python
1import numpy as np
2
3arr = np.array([
4    [1, 2, 3],
5    [4, 5, 6],
6    [7, 8, 9],
7])
8
9i = 1
10column = arr[:, i]
11
12print(column)
13print(column.shape)

Output:

text
[2 5 8]
(3,)

This is the usual answer when you want the column as a flat vector.

Keep the Column as 2D When Needed

If downstream code expects shape (rows, 1), slice a range instead:

python
1column_2d = arr[:, i:i+1]
2
3print(column_2d)
4print(column_2d.shape)

Output:

text
1[[2]
2 [5]
3 [8]]
4(3, 1)

This matters for matrix multiplication, feature matrices, and APIs that distinguish between vectors and column matrices.

Validate Indexes in Reusable Code

If the index is dynamic, it is worth validating both rank and bounds:

python
1import numpy as np
2
3
4def get_column(matrix: np.ndarray, i: int, keep_2d: bool = False) -> np.ndarray:
5    if matrix.ndim != 2:
6        raise ValueError("expected a 2D array")
7    if i < 0 or i >= matrix.shape[1]:
8        raise IndexError("column index out of range")
9
10    return matrix[:, i:i+1] if keep_2d else matrix[:, i]
11
12
13print(get_column(arr, 2))
14print(get_column(arr, 2, keep_2d=True).shape)

This avoids repeating shape assumptions throughout the codebase.

Higher Dimensions Need an Explicit Axis

If the array has more than two dimensions, "column" becomes ambiguous. In those cases, think in terms of axis selection rather than spreadsheet-style columns.

np.take can make the intent clearer:

python
1tensor = np.arange(2 * 3 * 4).reshape(2, 3, 4)
2
3slice_axis2 = np.take(tensor, indices=1, axis=2)
4print(slice_axis2.shape)

This is often easier to read than deeply nested slicing when working with higher-rank tensors.

View Versus Copy Matters

Simple slicing often returns a view into the original array:

python
1view_col = arr[:, 0]
2view_col[0] = 999
3
4print(arr[0, 0])  # 999

If you need an independent copy, call .copy():

python
1copied = arr[:, 0].copy()
2copied[1] = 123
3
4print(arr[1, 0])  # unchanged

This distinction is important in preprocessing pipelines where accidental mutation can corrupt the source matrix.

Common Pitfalls

The biggest mistake is using arr[:, i] when later code expects a (rows, 1) shape. NumPy will happily return a flat array, and the mismatch may only surface much later.

Another common issue is forgetting to validate bounds when the column index comes from user input or configuration.

Developers also sometimes treat higher-dimensional arrays as though they were always simple 2D tables. Once rank increases, axis selection needs to be explicit.

Finally, do not forget view semantics. A selected column may still be tied to the original array unless you copy it deliberately.

That is especially relevant in data-preprocessing code where one mutation can quietly affect later feature calculations.

Summary

  • Use arr[:, i] to get the ith column of a 2D NumPy array as a 1D vector.
  • Use arr[:, i:i+1] when you need to keep the result as a 2D column matrix.
  • Validate dimensions and bounds in reusable helpers.
  • For higher-rank arrays, think in terms of axis selection rather than generic "columns."
  • Be aware that slicing often returns a view, not an independent copy.

Course illustration
Course illustration

All Rights Reserved.