【发布时间】:2016-06-12 01:39:17
【问题描述】:
假设有一个 3 行 3 列的 numpy 矩阵。找到第一个对角线很容易,它是一种方法。
使用以下矩阵:
[[0,3,6]
[0,4,9]
[0,1,9]]
使用此代码:
import numpy
matrix.diagonals()
[0, 4, 9]
我怎样才能得到对角线?例如,对于上面的矩阵,我希望它返回:
[6, 4, 0]
【问题讨论】:
假设有一个 3 行 3 列的 numpy 矩阵。找到第一个对角线很容易,它是一种方法。
使用以下矩阵:
[[0,3,6]
[0,4,9]
[0,1,9]]
使用此代码:
import numpy
matrix.diagonals()
[0, 4, 9]
我怎样才能得到对角线?例如,对于上面的矩阵,我希望它返回:
[6, 4, 0]
【问题讨论】:
实现这一目标的最快方法是使用步幅。您的数组有一个 .strides 属性,它告诉您必须在内存中向前跳过多少字节才能到达每个维度中的下一个项目:
>>> a = np.array([[0, 3, 6], [0, 4, 9], [0, 1, 9]])
>>> a.strides
(24, 8)
对于正常的前向对角线,您必须向前跳过一行加一列,对于反向对角线,您必须向前跳过一行减去一列:
>>> a.strides[0] + a.strides[1]
32
>>> a.strides[0] - a.strides[1]
16
您现在可以construct 来自与原始数组相同的内存缓冲区的数组,但使用新的步幅(以及在反向对角线情况下从第一行的最后一列开始的非零偏移量):
>>> np.ndarray(shape=min(a.shape), dtype=a.dtype, buffer=a,
... offset=0, strides=a.strides[0]+a.strides[1])
array([0, 4, 9])
>>> np.ndarray(shape=min(a.shape), dtype=a.dtype, buffer=a,
... offset=a.strides[1] * (a.shape[1] - 1),
... strides=a.strides[0]+a.strides[1])
array([6, 4, 0])
这些实际上是原始数组内存的视图,即如果您修改它们的内容,原始数组也会改变,因此实际上没有内存分配或复制,只是包含对象的设置,所以它会尽可能快。
【讨论】:
我想这会做到:
In [29]: mm
Out[29]:
matrix([[0, 3, 6],
[0, 4, 9],
[0, 1, 9]])
In [30]: np.fliplr(mm)
Out[30]:
matrix([[6, 3, 0],
[9, 4, 0],
[9, 1, 0]])
In [31]: mm.diagonal()
Out[31]: matrix([[0, 4, 9]])
In [33]: np.fliplr(mm).diagonal()
Out[33]: matrix([[6, 4, 0]])
【讨论】:
您可以进行如下操作:
(1) 反转矩阵,(2) 得到对角线,(3) 反转对角线
import numpy
a = numpy.matrix([[0, 3, 6], [0, 4, 9], [0, 1, 9]])
print(numpy.diag(a))
print(numpy.diag(a[::-1])[::-1])
输出:
[0 4 9]
[6 4 0]
【讨论】:
In [240]: M=np.arange(9).reshape(3,3)
主对角线是M[i,j] for i==j,我们可以通过高级索引获得 i 和 j 的相同数组
In [241]: i=np.arange(3)
In [242]: M[i,i]
Out[242]: array([0, 4, 8])
通过颠倒 j 的顺序,我们得到另一个对角线
In [243]: M[i,i[::-1]]
Out[243]: array([2, 4, 6])
我怀疑对于大型数组,像这样反转索引比翻转矩阵更快。但是我们必须做一些时间来确定。
============
哎呀,我错了。 M.diagonal() 比我的显式索引快很多。对于N=1000。
In [259]: timeit M.diagonal();np.fliplr(M).diagonal()
100000 loops, best of 3: 3.63 µs per loop
In [260]: timeit i=np.arange(N);mm=M[i,i],M[i,i[::-1]]
10000 loops, best of 3: 51.3 µs per loop
【讨论】: