使numpy ndarray矩阵对称

时间:2015-03-06 17:35:39

标签: python matlab numpy matrix

我有一个70x70的numpy ndarray,主要是对角线。唯一的非对角线值是对角线以下。我想使矩阵对称。

作为Matlab世界的新手,我无法在没有循环的情况下使用它。在MATLAB中很简单:

W = max(A,A')

其中A'是矩阵转置,max()函数注意使W矩阵成对称。

在Python中也有一种优雅的方式吗?

实施例 样本A矩阵是:

1 0 0 0
0 2 0 0
1 0 2 0
0 1 0 3

所需的输出矩阵W为:

1 0 1 0
0 2 0 1
1 0 2 0
0 1 0 3

3 个答案:

答案 0 :(得分:19)

找到适合我的以下解决方案:

import numpy as np
W = np.maximum( A, A.transpose() )

答案 1 :(得分:2)

对于它的价值,使用你提到的MATLAB的numpy等价物比link @plonser添加的效率更高。

In [1]: import numpy as np
In [2]: A = np.zeros((4, 4))
In [3]: np.fill_diagonal(A, np.arange(4)+1)
In [4]: A[2:,:2] = np.eye(2)

# numpy equivalent to MATLAB:
In [5]: %timeit W = np.maximum( A, A.T)
100000 loops, best of 3: 2.95 µs per loop

# method from link
In [6]: %timeit W = A + A.T - np.diag(A.diagonal())
100000 loops, best of 3: 9.88 µs per loop

大型矩阵的时间可以类似地完成:

In [1]: import numpy as np
In [2]: N = 100
In [3]: A = np.zeros((N, N))
In [4]: A[2:,:N-2] = np.eye(N-2)
In [5]: np.fill_diagonal(A, np.arange(N)+1)
In [6]: print A
Out[6]: 
array([[   1.,    0.,    0., ...,    0.,    0.,    0.],
       [   0.,    2.,    0., ...,    0.,    0.,    0.],
       [   1.,    0.,    3., ...,    0.,    0.,    0.],
       ..., 
       [   0.,    0.,    0., ...,   98.,    0.,    0.],
       [   0.,    0.,    0., ...,    0.,   99.,    0.],
       [   0.,    0.,    0., ...,    1.,    0.,  100.]])

# numpy equivalent to MATLAB:
In [6]: %timeit W = np.maximum( A, A.T)
10000 loops, best of 3: 28.6 µs per loop

# method from link
In [7]: %timeit W = A + A.T - np.diag(A.diagonal())
10000 loops, best of 3: 49.8 µs per loop

并且N = 1000

# numpy equivalent to MATLAB:
In [6]: %timeit W = np.maximum( A, A.T)
100 loops, best of 3: 5.65 ms per loop

# method from link
In [7]: %timeit W = A + A.T - np.diag(A.diagonal())
100 loops, best of 3: 11.7 ms per loop

答案 2 :(得分:0)

使用NumPy triltriu的功能如下。它本质上是将下部三角形中的元素“镜像”到上部三角形中。

import numpy as np
A = np.array([[1, 0, 0, 0], [0, 2, 0, 0], [1, 0, 2, 0], [0, 1, 0, 3]])
W = np.tril(A) + np.triu(A.T, 1)

tril(m, k=0)获取矩阵m的下三角(返回第m对角线上方所有元素都为零的矩阵k的副本)。同样,triu(m, k=0)得到矩阵m的上三角(第k个对角线以下的所有元素都清零)。

为防止对角线被添加两次,必须使用np.tril(A) + np.triu(A.T, 1)np.tril(A, -1) + np.triu(A.T)将对角线从三角形之一中排除。

还请注意,这与使用maximum的行为略有不同。上部三角形中的所有元素,无论它们是否为最大值都将被覆盖。这意味着它们可以是任何值(例如naninf)。