2

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 I get the error message cannot assign to function call.

3 Answers 3

2

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]])
Sign up to request clarification or add additional context in comments.

3 Comments

Thats nice! I didn't know about cumsum function And do you an idea how to do it if the output wanted was [[1,0,0],[3,1,0],[2,3,1]]? Thank you :)
@Gon it depends, what would be the output for a 4x4 array? And 5x4?
Not sure if this is what you want but I provided an update
1

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)

1 Comment

That's very clever! thanks!
1

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]])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.