Randomly replace cells in a numpy array without replacement
Question:
I have a 25 x 25 numpy array filled with 0s. I want to randomly replace 0s within the array with 1s, with the number of 0s to be replaced defined by the user and ranging from 1 to 625. How can I do this without replacement becoming an issue given there are two coordinate values, x and y?
Code for generating a 25 x 25 array:
import numpy as np
Array = np.zeros((25,25))
Expected result on a 4 x 4 array:
Before
0,0,0,0
0,0,0,0
0,0,0,0
0,0,0,0
After (replace 1)
0,0,0,0
0,0,1,0
0,0,0,0
0,0,0,0
After (replace 16)
1,1,1,1
1,1,1,1
1,1,1,1
1,1,1,1
Answers:
Try:
import random
import numpy as np
SIZE = 25
howmany = 500
array = np.zeros((SIZE, SIZE), dtype=int)
xyset = set()
for i in range(SIZE):
for j in range(SIZE):
xyset.add((i, j))
for num in range(howmany):
xy = random.choice(list(xyset))
array[xy[0], xy[1]] = 1
xyset.discard(xy)
print(array)
Notes:
-
One may generate a unique sequence of random integers from 0 to 624, and mutate the corresponding element of the flattened array according to the generated sequence. Working with the flattened array, in this specific case, enables the development of a (relatively) concise code.
-
One can use np.random.choice
together with the argument replace=False
to generate a non-repetitive sequence of random numbers. You can see more information on NumPy docs.
Here is one of the solutions for a case with a 2D array of the size of 5×5 that undergoes 5 mutations:
import numpy as np
dim = 5 #<========== size of each axis of array -- in your case, it would be 25
num_mut = 5 #<========== number of mutations -- in your case it would be an integer from 0 to 624
Array = np.zeros((dim,dim))
Array_flat = Array.flatten()
print('before mutation:')
print(Array)
ind_mut = np.random.choice(dim*dim, size=num_mut, replace=False).tolist()
Array_flat[ind_mut]=1
Array_mut = Array_flat.reshape(Array.shape)
print('nafter mutation:')
print(Array_mut)
Output:
I have a 25 x 25 numpy array filled with 0s. I want to randomly replace 0s within the array with 1s, with the number of 0s to be replaced defined by the user and ranging from 1 to 625. How can I do this without replacement becoming an issue given there are two coordinate values, x and y?
Code for generating a 25 x 25 array:
import numpy as np
Array = np.zeros((25,25))
Expected result on a 4 x 4 array:
Before
0,0,0,0
0,0,0,0
0,0,0,0
0,0,0,0
After (replace 1)
0,0,0,0
0,0,1,0
0,0,0,0
0,0,0,0
After (replace 16)
1,1,1,1
1,1,1,1
1,1,1,1
1,1,1,1
Try:
import random
import numpy as np
SIZE = 25
howmany = 500
array = np.zeros((SIZE, SIZE), dtype=int)
xyset = set()
for i in range(SIZE):
for j in range(SIZE):
xyset.add((i, j))
for num in range(howmany):
xy = random.choice(list(xyset))
array[xy[0], xy[1]] = 1
xyset.discard(xy)
print(array)
Notes:
-
One may generate a unique sequence of random integers from 0 to 624, and mutate the corresponding element of the flattened array according to the generated sequence. Working with the flattened array, in this specific case, enables the development of a (relatively) concise code.
-
One can use
np.random.choice
together with the argumentreplace=False
to generate a non-repetitive sequence of random numbers. You can see more information on NumPy docs.
Here is one of the solutions for a case with a 2D array of the size of 5×5 that undergoes 5 mutations:
import numpy as np
dim = 5 #<========== size of each axis of array -- in your case, it would be 25
num_mut = 5 #<========== number of mutations -- in your case it would be an integer from 0 to 624
Array = np.zeros((dim,dim))
Array_flat = Array.flatten()
print('before mutation:')
print(Array)
ind_mut = np.random.choice(dim*dim, size=num_mut, replace=False).tolist()
Array_flat[ind_mut]=1
Array_mut = Array_flat.reshape(Array.shape)
print('nafter mutation:')
print(Array_mut)
Output: