user12368911
user12368911

Reputation:

Shuffling an array in python

I have this array:

arr=[[1,1,1],[0,0,0],[0,0,0]

I would like the 1's to be distributed in randomly in second, third and first row.

For example, a wanted result would be:

arr=[[1,1,0],[0,0,0],[0,1,0] or arr=[[1,0,0],[0,0,1],[0,1,0]

However, using

np.random.shuffle(arr)

results in shuffling the rows and not the elements.

Upvotes: 2

Views: 537

Answers (5)

Andy
Andy

Reputation: 3170

You could do something like

import numpy as np

arr = [[1, 1, 1], [0, 0, 0], [0, 0, 0]]

np.random.permutation(np.array(arr).reshape(1, 9)[0]).reshape(3, 3).tolist()

Output (yours may be different, because randomness):

[[0, 1, 1], [0, 0, 0], [0, 0, 1]]

Explanation:

  • np.array(x) converts the list x into a numpy array.
  • reshape(1, 9) takes [[1, 1, 1], [0, 0, 0], [0, 0, 0]] and returns [[1, 1, 1, 0, 0, 0, 0, 0, 0]], so we get its first element (the entire sublist) with [0].
  • np.random.permutation(x) takes a list x and returns a random shuffled copy.
    • We use this instead of the seemingly more obvious np.random.shuffle(x), which is destructive and shuffles the list in place instead of returning a copy.
  • reshape(3, 3) takes our (1, 9) list and turns it back into a (3, 3)
  • Finally, tolist() turns our numpy array back into a Python list.

Upvotes: 0

user1321988
user1321988

Reputation: 523

How about make an ndarray, flatten, shuffle, and reshape:

import numpy as np

arr = np.array([[1,1,1],[0,0,0],[0,0,0]])
flat = np.array(arr.flat)

np.random.shuffle(flat)

result_array = flat.reshape(arr.shape)

Upvotes: 2

mukulgarg94
mukulgarg94

Reputation: 51

You could deconstruct your array, shuffle it and construct it back

import numpy as np

arr=[[1,1,1],[0,0,0],[0,0,0]]

flat_arr = [item for sublist in arr for item in sublist]

np.random.shuffle(flat_arr)

arr=np.array(flat_arr)

np.split(arr,3)

Upvotes: 1

Patrick Artner
Patrick Artner

Reputation: 51643

Extending my comment with an example, leveraging itertools.chain and random.shuffle - as Lucas already provided the numpy solution:

import random
from itertools import chain 

arr=[[1,1,0],[0,0,0],[0,1,0]]    

# make it a 1-dim list
chained = list(chain.from_iterable(arr))

# shuffle it 
random.shuffle(chained)

# repartition it again
new = [chained[i:i+3] for i in range(0,9,3)]

print(new)

Outputs (several tries):

[[0, 0, 1], [0, 0, 1], [1, 0, 0]]

[[1, 0, 0], [1, 1, 0], [0, 0, 0]]

[[0, 0, 0], [1, 0, 0], [0, 1, 1]]

[[0, 0, 1], [0, 0, 0], [1, 0, 1]]

[[0, 0, 0], [0, 0, 1], [0, 1, 1]]

Upvotes: 4

Lucas
Lucas

Reputation: 675

You could create an extended list, shuffle it then group it again, like this:

import numpy as np

arr=[[1,1,1],[0,0,0],[0,0,0]]

extended_array = []
for array in arr:
    extended_array.extend(array)

np.random.shuffle(extended_array)

arr = list(zip(*[iter(extended_array)] * 3))

print(arr)

Possible output:

[(0, 0, 0), (0, 0, 1), (1, 0, 1)]

Upvotes: 2

Related Questions