Reputation:
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
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.
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)
tolist()
turns our numpy array back into a Python list.Upvotes: 0
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
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
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
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