使两条对角线都通过矩阵条目 (i,j) 的 Pythonic 方法

Pythonic way to get both diagonals passing through a matrix entry (i,j)

通过条目 (i,j) 获取矩阵中对角线元素列表的 Pythonic 方法是什么?

例如,给定一个矩阵:

[1  2  3   4  5]
[6  7  8   9 10]
[11 12 13 14 15]
[16 17 18 19 20]
[21 22 23 24 25]

和一个条目,比方说,(1,3)(代表元素 9)我怎样才能以 Pythonic 方式获得穿过 9 的对角线中的元素?基本上,[3,9,15][5,9,13,17,21] 都是。

使用带有一点偏移逻辑的np.diagonal

import numpy as np

lst = np.array([[1,  2,  3,   4,  5],
                [6,  7,  8,   9, 10],
                [11, 12, 13, 14, 15],
                [16, 17, 18, 19, 20],
                [21, 22, 23, 24, 25]])


i, j = 1, 3
major = np.diagonal(lst, offset=(j - i))
print(major)
array([ 3,  9, 15])

minor = np.diagonal(np.rot90(lst), offset=-lst.shape[1] + (j + i) + 1)
print(minor)
array([ 5,  9, 13, 17, 21])

索引ij是行和列。通过指定偏移量,numpy 知道从哪里开始为对角线选择元素。

对于主对角线,您想从第一行的 3 开始收集。因此,您需要将当前列索引减去当前行索引,以找出第 0th 行的正确列索引。与次对角线类似,阵列被翻转(旋转 90°)并重复该过程。

作为另一种替代方法,将数组拆开并用于形状为 (n*n) 的矩阵:

array = np.array([[1,  2,  3,   4,  5],
                  [6,  7,  8,   9, 10],
                  [11, 12, 13, 14, 15],
                  [16, 17, 18, 19, 20],
                  [21, 22, 23, 24, 25]])

x, y = 1, 3


a_mod = array.ravel()
size = array.shape[0]

if y >= x:
    diag = a_mod[y-x:(x+size-y)*size:size+1]
else:
    diag = a_mod[(x-y)*size::size+1]

if x-(size-1-y) >= 0:
    reverse_diag = array[:, ::-1].ravel()[(x-(size-1-y))*size::size+1]
else:
    reverse_diag = a_mod[x:x*size+1:size-1]

# diag         --> [ 3  9 15]
# reverse_diag --> [ 5  9 13 17 21]

必须进一步检查结果数组的正确性。这可以被开发来处理具有其他形状的矩阵,例如(n*m).