1

I have been trying to shuffle all the elements within a two dimensional numpy ndarray using 3 different methods. I've tried np.random.shuffle(), rng.shuffle(), and rng.permutation().

However, all these methods shuffle the elements along the rows, with the exception of rng.shuffle() which can shuffle along the columns if axis=1.

Moreover, none of the previous methods actually (changes contents) "cross" shuffles elements from different rows within the array, for example:

a = np.random.randint(0, 10, (3, 3))
> array([[5, 3, 0],  # 1  
       [9, 5, 2],  # 2
       [5, 0, 6]])  # 3

np.random.shuffle(a)
> array([[5, 0, 6],  # 3
       [5, 3, 0],  # 1
       [9, 5, 2]])  # 2

Though an example of the desired output would be something like this:

> array([[5, 5, 0],
       [0, 9, 5],
       [3, 6, 2]])

Is my desired output possible? And what is the exact different between these 3 methods? I tried reading the docs on random.shuffle(), rng.shuffle(), and rng.permutation(), but it was noncomprehensive.

Omar AlSuwaidi
  • 1,187
  • 2
  • 6
  • 26

1 Answers1

2

The shuffle function in your above snippet is functioning as intended. Array a only has 3 elements (the rows in your 2d array).

Because of this, when you call shuffle on a, it will only shuffle the rows.

If you wanted to shuffle every number together in your nd-array, you could flatten a to a 1x9 and shuffle that way.

a would then have 9 elements, each one gets shuffled among itself.

From here you can resize your 1x9 back into a 3x3 and achieve your desired result.

Gunner Stone
  • 997
  • 8
  • 26
  • That's a brilliant sneaky way! Though do you know the difference between apply each method, or are they all equivalent? – Omar AlSuwaidi Mar 06 '21 at 22:52
  • 1
    @OmarAlSuwaidi I think I found a pretty good answer here https://stackoverflow.com/questions/15474159/shuffle-vs-permute-numpy One returns a copy of a shuffled array, and the other shuffles it in-place. Very nuanced but each have their use cases – Gunner Stone Mar 06 '21 at 22:57
  • Awesome, MUCH appreciated! Though if you don't mind, ```rng.permutation(a.reshape(1, 9))``` doesn't seem to have an effect, but ```rng.permutation(a.reshape(9))``` does. Any clue why? – Omar AlSuwaidi Mar 06 '21 at 23:02
  • 1
    @OmarAlSuwaidi `reshape(1,9)` probably ends up looking like [[1],[2],...[9]] while `reshape(9)` probably looks like [1,2,3,...,9]. The latter is what we want. I'd probably output what both of those look like in the console to see what they specifically look like. – Gunner Stone Mar 06 '21 at 23:05