Numpy: affects diagonal matrix elements up to 1.10

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

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

numpy.fill_diagonal () , numpy.diag_indices () Only works with basic 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 arrays x, y, z.

matrix

+5
source share
3 answers

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

Passing a list of row indexes and a list of column indices allows you to directly and directly access locations (and efficiently). For instance:

>>> 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 the general case, for an array kxk called z , you can set the upper diagonal i th with

 z[np.arange(ki), np.arange(ki) + i] 

and lower lower diagonal i with

 z[np.arange(ki) + i, np.arange(ki)] 

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

 np.arange(ki) == ix[:-i] 
+4
source

Try the following:

 >>> A = np.zeros((6,6)) >>> i,j = np.indices(A.shape) >>> z = [1, 2, 3, 4, 5] 

Now you can intuitively access any diagonal:

 >>> A[i==j-1] = z >>> A array([[ 0., 1., 0., 0., 0., 0.], [ 0., 0., 2., 0., 0., 0.], [ 0., 0., 0., 3., 0., 0.], [ 0., 0., 0., 0., 4., 0.], [ 0., 0., 0., 0., 0., 5.], [ 0., 0., 0., 0., 0., 0.]]) 

In the same way, you can assign arrays A[i==j] , etc.

+4
source

Here is another approach just for fun. You can write your own diagonal function to return to the diagonal that you need.

 import numpy as np def diag(a, k=0): if k > 0: a = a[:, k:] elif k < 0: a = a[-k:, :] shape = (min(a.shape),) strides = (sum(a.strides),) return np.lib.stride_tricks.as_strided(a, shape, strides) a = np.arange(20).reshape((4, 5)) diag(a, 2)[:] = 88 diag(a, -2)[:] = 99 print(a) # [[ 0 1 88 3 4] # [ 5 6 7 88 9] # [99 11 12 13 88] # [15 99 17 18 19]] 
+1
source

Source: https://habr.com/ru/post/1210794/


All Articles