Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy: Affect diagonal elements of matrix prior to 1.10

I would like to change diagonal elements from a 2d matrix. These are both main and non-main diagonals.

numpy.diagonal() In NumPy 1.10, it will return a read/write view, Writing to the returned array will alter your original array.

numpy.fill_diagonal(), numpy.diag_indices() Only works with main-diagonal elements

Here is my use case: I want to recreate a matrix of the following form, which is very trivial using diagonal notation given that I have all the x, y, z as arrays.

matrix

like image 221
FooBar Avatar asked Jan 10 '15 11:01

FooBar


People also ask

How do you find the diagonal elements of a matrix in NumPy?

diagonal() With the help of Numpy matrix. diagonal() method, we are able to find a diagonal element from a given matrix and gives output as one dimensional matrix.

How does NumPy diagonal work?

NumPy: diag() function The diag() function is used to extract a diagonal or construct a diagonal array. If v is a 2-D array, return a copy of its k-th diagonal. If v is a 1-D array, return a 2-D array with v on the k-th diagonal. Diagonal in question.

Can we use NumPy for manipulating matrices?

NumPy can be used to perform a wide variety of mathematical operations on arrays. It adds powerful data structures to Python that guarantee efficient calculations with arrays and matrices and it supplies an enormous library of high-level mathematical functions that operate on these arrays and matrices.


1 Answers

You could always use slicing to assign a value or array to the diagonals.

Passing in a list of row indices and a list of column indices lets you access the locations directly (and efficiently). For example:

>>> z = np.zeros((5,5))
>>> z[np.arange(5), np.arange(5)] = 1 # diagonal is 1
>>> z[np.arange(4), np.arange(4) + 1] = 2 # first upper diagonal is 2
>>> z[np.arange(4) + 1, np.arange(4)] = [11, 12, 13, 14] # first lower diagonal values

changes the array of zeros z to:

array([[  1.,   2.,   0.,   0.,   0.],
       [ 11.,   1.,   2.,   0.,   0.],
       [  0.,  12.,   1.,   2.,   0.],
       [  0.,   0.,  13.,   1.,   2.],
       [  0.,   0.,   0.,  14.,   1.]])

In general for a k x k array called z, you can set the ith upper diagonal with

z[np.arange(k-i), np.arange(k-i) + i]

and the ith lower diagonal with

z[np.arange(k-i) + i, np.arange(k-i)]

Note: if you want to avoid calling np.arange several times, you can simply write ix = np.arange(k) once and then slice that range as needed:

np.arange(k-i) == ix[:-i]
like image 196
Alex Riley Avatar answered Sep 22 '22 05:09

Alex Riley