100

What is the difference between numpy.random.shuffle(x) and numpy.random.permutation(x)?

I have read the doc pages but I could not understand if there was any difference between the two when I just want to randomly shuffle the elements of an array.

To be more precise suppose I have an array x=[1,4,2,8].

If I want to generate random permutations of x, then what is the difference between shuffle(x) and permutation(x)?

Gabriel
  • 40,504
  • 73
  • 230
  • 404
DotPi
  • 3,977
  • 6
  • 33
  • 53

4 Answers4

133

np.random.permutation has two differences from np.random.shuffle:

  • if passed an array, it will return a shuffled copy of the array; np.random.shuffle shuffles the array inplace
  • if passed an integer, it will return a shuffled range i.e. np.random.shuffle(np.arange(n))

If x is an integer, randomly permute np.arange(x). If x is an array, make a copy and shuffle the elements randomly.

The source code might help to understand this:

3280        def permutation(self, object x):
...
3307            if isinstance(x, (int, np.integer)):
3308                arr = np.arange(x)
3309            else:
3310                arr = np.array(x)
3311            self.shuffle(arr)
3312            return arr
ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • 2
    When used on a `panda.Index`, only `permutation` works and `shuffle` doesn't. How does this case fit into your explanation? – Heisenberg Feb 19 '15 at 06:15
  • 1
    @Heisenberg `permutation` coerces its argument into an ndarray (by copying); `pandas.Index` is sufficiently different from an ndarray that `shuffle` won't work on it, but will work on an ndarray created from it. – ecatmur Feb 19 '15 at 10:39
37

Adding on to what @ecatmur said, np.random.permutation is useful when you need to shuffle ordered pairs, especially for classification:

from np.random import permutation
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data
y = iris.target

# Data is currently unshuffled; we should shuffle 
# each X[i] with its corresponding y[i]
perm = permutation(len(X))
X = X[perm]
y = y[perm]
hlin117
  • 20,764
  • 31
  • 72
  • 93
  • 1
    I keep getting this: TypeError: only integer scalar arrays can be converted to a scalar index – john k Nov 06 '17 at 21:57
  • 2
    To clarify @hlin117, this only works if x and y are numpy arrays. If you try to do it with pythons built-in lists it will throw the TypeError. – benjaminjsanders Mar 25 '19 at 23:21
3

The permutation() method returns a re-arranged array (and leaves the original array un-changed),this method will keep the original array intact and will return a shuffled array, for example x = [1,4,2,8] is the original array and the permutation method will return the rearranged array (lets say [8,4,1,2]).Now,you have two arrays, original array and the rearranged array.

In the other hand,

The shuffle() method makes changes to the original array,for example x = [1,4,2,8] is the original array and the shuffle method will return the shuffled array(lets say shuffled array is [8,4,1,2]). Now , the original array itself got changed to the Shuffled array, and you are only left with the shuffled array.

Reference :-https://www.w3schools.com/python/numpy_random_permutation.asp

1

Adding on @ecatmur, Here is a brief explanation. To start with I have created an array which is of shape 3,3 and has numbers from 0 to 8

import numpy as np
x1 = np.array(np.arange(0,9)).reshape(3,3) #array with shape 3,3 and have numbers from 0 to 8

#step1: using np.random.permutation
x_per = np.random.permutation(x1)
print('x_per:', x_per)
print('x_1:', x_1)
#Inference: x1 is not changed and x_per has its rows randomly changed

#The outcome will be 
x1: [[0 1 2]
     [3 4 5]
     [6 7 8]]
x_per:[[3 4 5]
       [0 1 2]
       [6 7 8]]
#Lets apply shuffling
x2 = np.array(range(9)).reshape(3,3)
x2_shuffle = np.random.shuffle(x2)
print('x2_shuffle:', x2_shuffle)
print('x2', x2)

#Outcome: 
x2_shuffle: None
x2 [[3 4 5]
    [0 1 2]
    [6 7 8]]

Key inference is: When x is an array, both numpy.random.permutation(x) and numpy.random.shuffle(x) can permute the elements in x randomly along the first axis. numpy.random.permutation(x) actually returns a new variable and the original data is not changed. Where as numpy.random.shuffle(x) has changed original data and does not return a new variable. I just tried to show with an example so it can help others. Thanks!!

Mohanrac
  • 85
  • 6