在 NumPy Python 中如何进行反对角线操作

13

假设我有这样一个东西:

(numpy数组)
a=
[0  1  2  3],
[4  5  6  7],
[8  9 10  11]

如何获得 [1,1] 对应的反对角线 [2,5,8]?根据numpy,a.diagonal(0) = [0,5,10] 代表其对角线为零。这是可能的吗?我的原始问题是一个8x8(0:7)...希望这有所帮助。


1
有两个答案似乎不够通用,因为你的样本 a 很小。你想让 [2,2] 的答案是 [7,10] 吗?相关问题,你能在另一个方向上是矩形(高而不宽)吗? - Phil Cooper
我的例子是一个8乘8的矩阵(0:7)...希望这有所帮助。 - MasterWizard
4个回答

17

每行获得一个新的反转数组。

>>> import numpy as np
>>> a = np.array([
...     [0, 1, 2, 3],
...     [4, 5, 6, 7],
...     [8, 9, 10, 11]
... ])
>>> a[:, ::-1]
array([[ 3,  2,  1,  0],
       [ 7,  6,  5,  4],
       [11, 10,  9,  8]])
>>> a[:, ::-1].diagonal(1)
array([2, 5, 8])

或者使用numpy.fliplr


>>> np.fliplr(a).diagonal(1)
array([2, 5, 8])

1
请注意,对于一般情况,这需要从数组的另一侧计算偏移量,例如,您将需要在计算中使用 a.shape - wim
@wim,你说得对。就这个问题而言,你的答案更加优雅。感谢你的评论。+1 - falsetru
在我的程序中,我不知道如何获取对角函数内部的“1”?我该怎么做? - MasterWizard
@AhmedNassar,你可以使用max(a.shape[1]-a.shape[0], 0)代替1 - falsetru
抱歉,我有些困惑,我该如何使用它。也许我没有表达清楚,假设我想要得到[3,6,9],我应该执行什么操作才能立即得到它,而不必查看表格。 - MasterWizard
@AhmedNassar,尝试使用a[:, ::-1].diagonal(0)np.fliplr(a).diagonal(0) - falsetru

5

将数组翻转并使用相同的方法:

np.flipud(a).diagonal(0)[::-1]

4
另一种实现方法是使用np.rot90
import numpy as np

a = np.array([[0,  1,  2,  3],
              [4,  5,  6,  7],
              [8,  9, 10,  11]])            

my_diag = np.rot90(a).diagonal(-1)

结果:

>>> my_diag
array([2, 5, 8])

0
到目前为止有许多答案。@Akavall最接近,因为您需要旋转或翻转并转置(等效操作)。我还没有看到OP对矩形的“长”部分的预期行为的回应。
正方形矩阵的通用解决方案:
a = array([[ 0,  1,  2,  3,  4],
           [ 5,  6,  7,  8,  9],
           [10, 11, 12, 13, 14],
           [15, 16, 17, 18, 19],
           [20, 21, 22, 23, 24]])
>>> [(i, np.rot90(a).diagonal(2*i-a.shape[0]+1)) for i in range(a.shape[0])]
[(0, array([0])),
 (1, array([ 2,  6, 10])),
 (2, array([ 4,  8, 12, 16, 20])),
 (3, array([14, 18, 22])),
 (4, array([24]))]

作为一个函数:
def reverse_diag(arr, n):
    idx = 2*n - arr.shape[0]+1
    return np.rot90(arr).diagonal(idx)

使用a[:np.min(a.shape),:np.min(a.shape)]可以将原始矩阵变成正方形。

编辑:OP表示数组是正方形... 最终答案如上所述。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接