2016-06-12 149 views
2

可以说有3行3列的numpy矩阵。找到第一个对角线很容易,它是一种方法。如何查找二维矩阵的两个对角线?

用下面的矩阵:

[[0,3,6] 

[0,4,9] 

[0,1,9]] 

使用此代码:

import numpy 
matrix.diagonals() 
[0, 4, 9] 

我怎样才能得到相反的对角线?例如上述矩阵我想它返回:

[6, 4, 0] 

回答

1

我想这会做到这一点:

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

您可以进行如下操作:
(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] 
1
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 
3

达到此目的的最快方法是使用步幅。你的阵列有一个.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]) 

这些实际上是视图到原始数组的内存,即如果您修改其内容,原始数组也会改变,所以实际上没有内存分配或复制进行,只是设置包含的对象,所以它会尽可能快地得到。