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]]Method 1: Using Advanced Indexing (Recommended)
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] = tempMethod 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.