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

Numpy: Affect diagonal elements of matrix prior to 1.10

我想更改二维矩阵的对角线元素。这些都是主对角线和 [​​=34=] 对角线。

numpy.diagonal() 在 NumPy 1.10 中,它将 return 一个 read/write 视图,写入 returned array 将改变你的原始数组。

numpy.fill_diagonal(), numpy.diag_indices() 仅适用于 main-diagonal 个元素

这是我的用例:我想重新创建以下形式的矩阵,考虑到我拥有所有 xy, z 作为数组。

试试这个:

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

您始终可以使用切片将值或数组分配给对角线。

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

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

一般来说,对于名为 zk x k 数组,您可以将第 i 个上对角线设置为

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

和第 i 个下对角线

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

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

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

这是另一种方法,只是为了好玩。您可以将自己的对角线函数编写到 return 您需要的对角线视图。

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