我用numpy好几年了,从来没见过这样的功能。
这是您可以做到的一种方法(不一定是最有效的):
In [47]: a
Out[47]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
In [48]: np.concatenate([np.diagonal(a[::-1,:], k)[::(2*(k % 2)-1)] for k in range(1-a.shape[0], a.shape[0])])
Out[48]: array([ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15])
将单行分解为单独的步骤:
a[::-1, :] 反转行:
In [59]: a[::-1, :]
Out[59]:
array([[12, 13, 14, 15],
[ 8, 9, 10, 11],
[ 4, 5, 6, 7],
[ 0, 1, 2, 3]])
(也可以写成a[::-1] 或np.flipud(a)。)
np.diagonal(a, k) 提取kth 对角线,其中k=0 是主对角线。所以,例如,
In [65]: np.diagonal(a[::-1, :], -3)
Out[65]: array([0])
In [66]: np.diagonal(a[::-1, :], -2)
Out[66]: array([4, 1])
In [67]: np.diagonal(a[::-1, :], 0)
Out[67]: array([12, 9, 6, 3])
In [68]: np.diagonal(a[::-1, :], 2)
Out[68]: array([14, 11])
在列表推导中,k 给出了要提取的对角线。我们想要反转每隔一个对角线中的元素。表达式 2*(k % 2) - 1 给出的值是 1、-1、1、...,因为 k 从 -3 到 3 不等。使用 [::1] 进行索引使被索引的数组的顺序保持不变,而使用 [::-1] 进行索引反转数组的顺序。所以np.diagonal(a[::-1, :], k)[::(2*(k % 2)-1)] 给出了kth 对角线,但所有其他对角线都颠倒了:
In [71]: [np.diagonal(a[::-1,:], k)[::(2*(k % 2)-1)] for k in range(1-a.shape[0], a.shape[0])]
Out[71]:
[array([0]),
array([1, 4]),
array([8, 5, 2]),
array([ 3, 6, 9, 12]),
array([13, 10, 7]),
array([11, 14]),
array([15])]
np.concatenate() 将它们全部放入一个数组中:
In [72]: np.concatenate([np.diagonal(a[::-1,:], k)[::(2*(k % 2)-1)] for k in range(1-a.shape[0], a.shape[0])])
Out[72]: array([ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15])