NumPy Shuffle Array

Tech reviewed: Deepak Prasad
NumPy Shuffle Array

NumPy arrays can be shuffled with np.random.shuffle(), Generator.shuffle() from np.random.default_rng(), or permutation() when you need a shuffled copy or reusable index order. shuffle() changes the original array in place and returns None. permutation() returns a new shuffled array and leaves the original unchanged.

There is no common top-level np.shuffle() function. Searches for “np shuffle” usually mean np.random.shuffle() or rng.shuffle().

Tested on: Python 3.13.3; NumPy 2.2.3; kernel 6.14.0-37-generic.


NumPy shuffle quick reference

Task Use
Shuffle an array in place np.random.shuffle(arr)
Shuffle using modern NumPy random API rng.shuffle(arr)
Get a shuffled copy without changing original rng.permutation(arr)
Shuffle two arrays in the same order One permutation index applied to both
Shuffle two Python lists together Same index order on both lists
Shuffle rows of a 2D array shuffle() on axis 0 (default)
Reproducible shuffle np.random.default_rng(seed)
Avoid changing original array permutation(), not shuffle()

np.shuffle vs np.random.shuffle

Many tutorials say “np shuffle,” but the callable is np.random.shuffle(x)—not np.shuffle(). For new code, NumPy’s docs recommend the Generator API:

python
import numpy as np

rng = np.random.default_rng()
arr = np.array([1, 2, 3, 4, 5])
rng.shuffle(arr)
print(arr)
Output

np.random.shuffle() still works and modifies the array in place. Prefer default_rng().shuffle() for clearer seeding and behavior aligned with current NumPy guidance. For other random draws and sampling patterns, see NumPy random examples.


Shuffle a NumPy array using np.random.shuffle()

python
import numpy as np

arr = np.array([1, 2, 3, 4, 5])
np.random.shuffle(arr)
print(arr)
Output

You should see the same five numbers in a random order. The return value is None—do not write:

python
arr = np.random.shuffle(arr)  # wrong: arr becomes None
Output

Use shuffle() when you no longer need the original order.


Shuffle an array using default_rng().shuffle()

python
import numpy as np

arr = np.array([1, 2, 3, 4, 5])
rng = np.random.default_rng(42)
rng.shuffle(arr)
print(arr)
Output

With seed 42, you get the same shuffled order every run—useful for tests and reproducible ML splits.

python
rng = np.random.default_rng(42)
arr2 = np.array([1, 2, 3, 4, 5])
rng.shuffle(arr2)
print(arr2)
Output

Running again with the same seed and starting array yields the same permutation.


shuffle() vs permutation()

Feature shuffle() permutation()
Changes original array Yes No
Returns new array No Yes
Return value None Shuffled array
Best for In-place randomization Keeping original; reusable indexes
Two arrays together Not directly Yes—one index vector for both
python
import numpy as np

orig = np.array([10, 20, 30, 40])
rng = np.random.default_rng(0)

shuffled_copy = rng.permutation(orig)
print(orig)
print(shuffled_copy)
Output

orig stays [10, 20, 30, 40]; shuffled_copy holds a permuted version. Use shuffle() when in-place is fine; use permutation() when you need the old data or a shared index for multiple arrays.


Shuffle two NumPy arrays together

Features and labels must stay paired after shuffling. Build one index order and apply it to both arrays:

python
import numpy as np

x = np.array([1, 2, 4, 3])
y = np.array([10, 20, 40, 30])

rng = np.random.default_rng(42)
idx = rng.permutation(len(x))

x = x[idx]
y = y[idx]
print(x)
print(y)
Output

You should see matching pairs: 3 with 30, 4 with 40, and so on—same shuffle, aligned elements.

Check len(x) == len(y) before indexing. Shuffling x and y with separate random calls breaks pairing—common bug in train/test splits.

Alternative with np.random.shuffle on an index vector (legacy style):

python
idx = np.arange(len(x))
np.random.shuffle(idx)
x, y = x[idx], y[idx]
Output

Shuffle two Python lists together

The same index idea works for Python lists—useful for “shuffle two lists together” queries:

python
import numpy as np

names = ["Ann", "Bob", "Cal"]
scores = [90, 85, 88]

idx = np.random.default_rng(1).permutation(len(names))
names_shuf = [names[i] for i in idx]
scores_shuf = [scores[i] for i in idx]
print(names_shuf, scores_shuf)
Output

For small plain lists you can also use random.sample(range(len(names)), len(names)) as indexes. When data is already NumPy, permutation() is the usual choice.


Shuffle rows of a 2D NumPy array

shuffle() and rng.shuffle() operate along the first axis (axis 0). For a 2D array, rows are reordered; values within each row stay put:

python
import numpy as np

matrix = np.array([[1, 2], [3, 4], [5, 6]])
rng = np.random.default_rng(0)
rng.shuffle(matrix)
print(matrix)
Output

You should see the same three rows permuted—e.g. [5, 6] first—not every cell scattered independently.


Shuffle columns or shuffle within each row

Default shuffle() does not shuffle columns or individual cells inside rows.

Shuffle columns (reorder column indices):

python
col_idx = rng.permutation(matrix.shape[1])
matrix = matrix[:, col_idx]
Output

Shuffle values inside each row (row-wise logic):

python
for i in range(matrix.shape[0]):
    rng.shuffle(matrix[i])
Output

Use these when row-only shuffling is not what you need.


Reproducible NumPy shuffle with seed

Without a fixed seed, each run produces a different order. For repeatable examples or experiments:

python
import numpy as np

rng = np.random.default_rng(123)
arr = np.array([1, 2, 3, 4, 5])
rng.shuffle(arr)
Output

Prefer default_rng(seed) over legacy np.random.seed() for new code—it keeps generator state localized and matches current NumPy practice.


Mistakes to avoid

  • Calling np.shuffle instead of np.random.shuffle or rng.shuffle.
  • Assigning arr = np.random.shuffle(arr)—the result is None.
  • Forgetting that shuffle() mutates the original array.
  • Shuffling x and y with different random operations—pairing breaks.
  • Mismatched lengths between two arrays you shuffle together.
  • Expecting a 2D shuffle() to randomize every element instead of rows.
  • Using shuffle() when you must keep the original array—use permutation().

Summary

Use np.random.shuffle() or rng.shuffle() to shuffle a NumPy array in place. Use rng.permutation() for a shuffled copy or a single index order shared across arrays. To shuffle two arrays or lists together, apply one permutation(len(arr)) to both. On 2D arrays, default shuffle reorders rows only. For reproducible results, use np.random.default_rng(seed).

See the NumPy Generator.shuffle docs and permutation for full API details.


Frequently Asked Questions

1. Is there an np.shuffle function in NumPy?

No common top-level np.shuffle—use np.random.shuffle(arr) or rng.shuffle(arr) from np.random.default_rng() for in-place shuffling.

2. Does np.random.shuffle return a shuffled array?

No—it modifies the array in place along the first axis and returns None. Use rng.permutation(arr) when you need a shuffled copy.

3. How do you shuffle two NumPy arrays together?

Build one index order with rng.permutation(len(arr)) and apply the same indexes to both arrays so paired elements stay aligned.

4. What does shuffle do to a 2D NumPy array?

It shuffles along axis 0 by default—row order changes, but values inside each row stay in the same order.

5. How do I get a reproducible shuffle?

Create a generator with np.random.default_rng(seed) and call rng.shuffle(arr) or rng.permutation(arr) with the same seed.
Azka Iftikhar

Computer Scientist

Proficient in multiple programming languages, including C++, Golang, and Java, she brings a versatile skillset to tackle a wide array of challenges. Experienced Computer Scientist and Web Developer, she excels as a MERN Stack Expert.

  • C (programming language)
  • Java (programming language)
  • Go (programming language)