Home > Software engineering >  diagonal of array in numpy
diagonal of array in numpy

Time:12-27

If I have the array [[1,0,0],[0,1,0],[0,0,1]] (let's call it So) which is done as numpy.eye(3). How can I get that the elements below the diagonal are only 2 and 3 like this [[1,0,0],[2,1,0],[3,2,1]] ?? How can I assign vectors of an array to a different set of values?

I know I could use numpy.concatenate to join 3 vectors and I know how to change rows/columns but I can't figure out how to change diagonals below the main diagonal.

I tried to do np.diagonal(So,-1)=2*np.diagonal(So,-1) to change the diagonal right below the main diagonal but it appeared "cannot assign to function call".

Any help would be appreciated :)

CodePudding user response:

I would not start from numpy.eye but rather numpy.ones and use numpy.tril cumsum to compute the next numbers on the lower triangle:

import numpy as np
np.tril(np.ones((3,3))).cumsum(axis=0).astype(int)

output:

array([[1, 0, 0],
       [2, 1, 0],
       [3, 2, 1]])
reversed output (from comment)

Assuming the array is square

n = 3
a = np.tril(np.ones((n,n)))
(a*(n 2)-np.eye(n)*n-a.cumsum(axis=0)).astype(int)

Output:

array([[1, 0, 0],
       [3, 1, 0],
       [2, 3, 1]])

Output for n=5:

array([[1, 0, 0, 0, 0],
       [5, 1, 0, 0, 0],
       [4, 5, 1, 0, 0],
       [3, 4, 5, 1, 0],
       [2, 3, 4, 5, 1]])

CodePudding user response:

You can use np.fill_diagonal and index the matrix so the principal diagonal of your matrix is the one you want. This suposing you want to put other values than 2 and 3 is the a good solution:

import numpy as np

q = np.eye(3)


#if you want the first diagonal below the principal
# you can call q[1:,:] (this is not a 3x3 or 2x3 matrix but it'll work)

val =2
np.fill_diagonal(q[1:,:], val)
#note that here you can use an unique value 'val' or 
# an array with values of corresponding size
#np.fill_diagonal(q[1:,:], [2, 2])

#then you can do the same on the last one column

np.fill_diagonal(q[2:,:], 3)

CodePudding user response:

You could follow this approach:

def func(n):
...     return np.array([np.array(list(range(i, 0, -1))   [0,] * (n - i)) for i in range(1, n   1)])

func(3)

OUTPUT

array([[1, 0, 0],
       [2, 1, 0],
       [3, 2, 1]])
  • Related