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 个元素
这是我的用例:我想重新创建以下形式的矩阵,考虑到我拥有所有 x、y, 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.]])
一般来说,对于名为 z
的 k 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]]
我想更改二维矩阵的对角线元素。这些都是主对角线和 [=34=] 对角线。
numpy.diagonal() 在 NumPy 1.10 中,它将 return 一个 read/write 视图,写入 returned array 将改变你的原始数组。
numpy.fill_diagonal(), numpy.diag_indices() 仅适用于 main-diagonal 个元素
这是我的用例:我想重新创建以下形式的矩阵,考虑到我拥有所有 x、y, 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.]])
一般来说,对于名为 z
的 k 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]]