1

I have a 2D numpy array which has only 0s in (N,N) size. I randomly want to insert twelve 1s to this array while keeping the diagonal locations' value equal to 0. What I have tried until now is :

import numpy as np def func(N=20): x= np.zeros((N,N)) for m in range(N): for n in range(N): if m == n: x[m][n] == 0 else: if np.count_nonzero(x) <= 12: x.fill(1) return (np.count_nonzero) print (x) 

The output I am getting is an N,N array full of 1s. I cannot stop inserting the 1s after their quantity reaches to 12. How can I fix it?

1 Answer 1

1

Since you are using NumPy and if you are okay with an alternate vectorized solution, here's one with masking and choosing those places with np.random.choice -

def random_off_diag_fill(N, num_rand = 12, fillval=1): # Initialize array x= np.zeros((N,N),dtype=type(fillval)) # Generate flat nondiagonal indices using masking idx = np.flatnonzero(~np.eye(N,dtype=bool)) # Select num_rand random indices from those and set those # in a flattened view of the array to be as fillval x.ravel()[np.random.choice(idx, num_rand, replace=0)] = fillval return x 

Sample runs -

In [57]: random_off_diag_fill(N=8, num_rand=12, fillval=1) Out[57]: array([[0, 0, 0, 0, 0, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 1, 0, 0], [0, 0, 1, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 1, 0, 0, 0, 0, 0]]) In [63]: random_off_diag_fill(N=5, num_rand=12, fillval=2.45) Out[63]: array([[ 0. , 0. , 0. , 0. , 2.45], [ 2.45, 0. , 2.45, 0. , 2.45], [ 0. , 2.45, 0. , 2.45, 2.45], [ 2.45, 2.45, 0. , 0. , 0. ], [ 2.45, 2.45, 0. , 2.45, 0. ]]) 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! It was exactly what I was searching for!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.