Skip to content

Python NumPy: How to Swap Two Rows in a NumPy Array

Learn efficient methods to swap rows in a NumPy array using advanced indexing, temporary variables, or circular shifts for data preprocessing and matrix manipulation.

Swapping rows in a NumPy array is a common operation in data preprocessing, matrix manipulation, and algorithm implementation. Whether you need to reorder data for analysis, implement sorting algorithms, or rearrange matrices for linear algebra operations, NumPy provides several efficient ways to exchange rows.

This guide covers four practical methods with clear examples and outputs.

Sample Array

All examples use the following 2D NumPy array:

import numpy as np

arr = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
    [10, 11, 12]
])
print(arr)

Output:

[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]

The most concise and Pythonic way to swap two rows is using NumPy's advanced indexing. Assign the rows in reversed order simultaneously:

import numpy as np

arr = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
    [10, 11, 12]
])

arr[[0, 3]] = arr[[3, 0]]

print(arr)

Output:

[[10 11 12]
 [ 4  5  6]
 [ 7  8  9]
 [ 1  2  3]]

Rows 0 and 3 are swapped in a single line. This works because NumPy evaluates the right side first, then assigns both rows simultaneously.

Method 2: Using Fancy Indexing to Reorder Multiple Rows

If you need to rearrange multiple rows at once - not just swap two - specify the desired row order as a list of indices:

import numpy as np

arr = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
])

print("Original:")
print(arr)

reordered = arr[[2, 0, 1]]

print("\nReordered:")
print(reordered)

Output:

Original:
[[1 2 3]
 [4 5 6]
 [7 8 9]]

Reordered:
[[7 8 9]
 [1 2 3]
 [4 5 6]]

The index list [2, 0, 1] means: take row 2 first, then row 0, then row 1. This creates a new array - the original is unchanged.

Method 3: Using Direct Assignment with a Temporary Copy

This method mirrors the classic variable-swap pattern using a temporary variable. It's explicit and easy to understand:

import numpy as np

arr = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
])

print("Before swap:")
print(arr)

temp = arr[1].copy()
arr[1] = arr[2]
arr[2] = temp

print("\nAfter swap:")
print(arr)

Output:

Before swap:
[[1 2 3]
 [4 5 6]
 [7 8 9]]

After swap:
[[1 2 3]
 [7 8 9]
 [4 5 6]]

Why .copy() Is Required

Without .copy(), the temporary variable temp would be a view of the original row, not an independent copy. When arr[1] is overwritten, temp would also change:

import numpy as np

arr = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
])

temp = arr[1]        # temp points to the same memory as arr[1]
arr[1] = arr[2]      # This overwrites arr[1], which also changes temp!
arr[2] = temp        # Now temp contains [7, 8, 9] (the overwritten value)

print(arr)

Output:

[[1 2 3]
 [7 8 9]
 [7 8 9]]

Both rows end up with the same values - the swap fails silently.

The correct approach:

temp = arr[1].copy()
arr[1] = arr[2]
arr[2] = temp

Method 4: Using np.roll() for Circular Row Shifts

np.roll() shifts all rows by a specified number of positions, wrapping rows from the bottom to the top (or vice versa). This is not a swap of two specific rows but rather a circular rotation:

import numpy as np

arr = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
    [10, 11, 12]
])

print("Original:")
print(arr)

rolled = np.roll(arr, shift=2, axis=0)

print("\nAfter rolling by 2:")
print(rolled)

Output:

Original:
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]

After rolling by 2:
[[ 7  8  9]
 [10 11 12]
 [ 1  2  3]
 [ 4  5  6]]

The last two rows wrap around to the top. This is useful for cyclic data but is not a targeted swap of two specific rows.

Creating a Reusable Swap Function

For repeated use, wrap the swap logic in a function:

import numpy as np


def swap_rows(arr, row1, row2):
    """Swap two rows in a NumPy array in place."""
    arr[[row1, row2]] = arr[[row2, row1]]


arr = np.array([
    [1, 1, 1],
    [2, 2, 2],
    [3, 3, 3],
    [4, 4, 4]
])

print("Before:")
print(arr)

swap_rows(arr, 0, 3)

print("\nAfter swapping rows 0 and 3:")
print(arr)

Output:

Before:
[[1 1 1]
 [2 2 2]
 [3 3 3]
 [4 4 4]]

After swapping rows 0 and 3:
[[4 4 4]
 [2 2 2]
 [3 3 3]
 [1 1 1]]

Swapping Columns Instead of Rows

The same techniques work for columns - just apply the indexing to the column axis:

import numpy as np

arr = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
])

arr[:, [0, 2]] = arr[:, [2, 0]]
print(arr)

Output:

[[3 2 1]
 [6 5 4]
 [9 8 7]]

Method Comparison

Method Modifies Original Swaps Specific Rows Best For
arr[[i, j]] = arr[[j, i]] Yes Yes Swapping two specific rows - recommended
arr[[2, 0, 1]] (fancy indexing) No (creates copy) Yes (any reordering) Rearranging multiple rows at once
Temp variable with .copy() Yes Yes Explicit, readable swap logic
np.roll() No (creates copy) No (circular shift) Rotating all rows cyclically

For most use cases, advanced indexing (arr[[i, j]] = arr[[j, i]]) is the best choice - it's concise, efficient, modifies the array in place, and clearly communicates the intent of swapping two rows.

Navigation