Numpy:影响矩阵之前的对角元素1.10

问题描述:

我想更改2d矩阵的对角线元素。这些都是主对角线和非主对角线。Numpy:影响矩阵之前的对角元素1.10

numpy.diagonal() 在NumPy的1.10,它会返回一个读/写视图,以书面形式向返回 阵列将改变原来的数组。

numpy.fill_diagonal()numpy.diag_indices() 只有主对角线元素的作品

这是我用例:我要重新创建下面的表格,这是一个矩阵考虑到我已经将所有的x,y,z作为数组,所以使用对角线符号很平凡。

matrix

+0

'numpy.diag'呢? – talonmies

+1

我认为'np.diag'调用'np.diagonal',它在Numpy 1.10之前呈现[难度](http://docs.scipy.org/doc/numpy/reference/generated/numpy.diagonal.html)当试图将值写入数组时。 –

+0

也许看看['scipy.sparse.diags'](http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.diags.html)和['scipy 。疏。dia_matrix'](http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.dia_matrix.htm)。 –

您总是可以使用切片来分配值o r数组到对角线。

传递行索引列表和列索引列表可让您直接(和高效地)访问位置。例如:

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

改变零z的数组:

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

通常,对于一个k x k阵列称为z,可以设置i个上位对角线

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

i th对角线较低

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

注意:如果你想避免调用np.arange几次,你可以简单地写ix = np.arange(k)一次,然后切片该范围需要:

np.arange(k-i) == ix[:-i] 

试试这个:

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

现在你可以直观地访问任何对角线:

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

在您可以指定数组A[i==j]以同样的方式,等

+0

没有比较@ajcrs答案的性能,但为了简单起见,我喜欢这个。 – FooBar

+0

@FooBar这个方法在语法上比我的语法简单得多:-)但是在性能方面,为较大的矩阵构造一个掩码(使用'i == j-1')效率不高。在1000x1000矩阵中,设置第一个较高对角线比直接指定索引要慢100倍左右。这是因为你需要进行一百万次'=='比较来构建布尔掩码(更不用说在存储器中有大的布尔矩阵)。当然,这个问题取决于你的用例。 –

这里只是为了好玩的另一种方法。您可以编写自己的对角线函数来返回所需对角线的视图。

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