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:
import numpy as np
rng = np.random.default_rng()
arr = np.array([1, 2, 3, 4, 5])
rng.shuffle(arr)
print(arr)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()
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
np.random.shuffle(arr)
print(arr)You should see the same five numbers in a random order. The return value is None—do not write:
arr = np.random.shuffle(arr) # wrong: arr becomes NoneUse shuffle() when you no longer need the original order.
Shuffle an array using default_rng().shuffle()
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
rng = np.random.default_rng(42)
rng.shuffle(arr)
print(arr)With seed 42, you get the same shuffled order every run—useful for tests and reproducible ML splits.
rng = np.random.default_rng(42)
arr2 = np.array([1, 2, 3, 4, 5])
rng.shuffle(arr2)
print(arr2)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 |
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)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:
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)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):
idx = np.arange(len(x))
np.random.shuffle(idx)
x, y = x[idx], y[idx]Shuffle two Python lists together
The same index idea works for Python lists—useful for “shuffle two lists together” queries:
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)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:
import numpy as np
matrix = np.array([[1, 2], [3, 4], [5, 6]])
rng = np.random.default_rng(0)
rng.shuffle(matrix)
print(matrix)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):
col_idx = rng.permutation(matrix.shape[1])
matrix = matrix[:, col_idx]Shuffle values inside each row (row-wise logic):
for i in range(matrix.shape[0]):
rng.shuffle(matrix[i])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:
import numpy as np
rng = np.random.default_rng(123)
arr = np.array([1, 2, 3, 4, 5])
rng.shuffle(arr)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.shuffleinstead ofnp.random.shuffleorrng.shuffle. - Assigning
arr = np.random.shuffle(arr)—the result isNone. - Forgetting that
shuffle()mutates the original array. - Shuffling
xandywith 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—usepermutation().
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.

