I want to make a numpy array that looks like this:
m = [1, 1, 1, 0, 0, 0, 0, 0, 0
0, 0, 0, 1, 1, 1, 0, 0, 0
0, 0, 0, 0, 0, 0, 1, 1, 1]
I have seen this answer Make special diagonal matrix in Numpy and I have this:
a = np.zeros(3,9)
a[0, 0] = 1
a[0, 1] = 1
a[0, 2] = 1
a[1, 3] = 1
a[1, 4] = 1
a[1, 5] = 1
a[2, 6] = 1
a[2, 7] = 1
a[2, 8] = 1
But I want to use a 'for' cicle, How I can fill the diagonal efficiently?
One way is to simply stretch an identity array horizontally;
> np.repeat(np.identity(3, dtype=int), 3, axis=1)
array([[1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 1]])
If m
denotes the number of 1
s in a row and n
the number of rows, two approaches could be listed to solve it.
Using np.kron
this is straight-forward, like so -
def kron_based(m,n):
return np.kron(np.eye(n,dtype=int), np.ones(m,dtype=int))
Using zeros initialization and filling would be -
def initialization_based(m,n):
A = np.zeros((n,n*m),dtype=int)
A.reshape(n,n,m)[np.eye(n,dtype=bool)] = 1
return A
Sample run -
In [54]: m = 4 # Number of 1s in a row. Note that this is 3 for your case
...: n = 3 # Number of rows
...:
In [55]: initialization_based(m,n)
Out[55]:
array([[1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]])
In [56]: kron_based(m,n)
Out[56]:
array([[1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With