使numpy ndarray矩阵对称

时间:2021-11-03 21:21:38

I have a 70x70 numpy ndarray, which is mainly diagonal. The only off-diagonal values are the below the diagonal. I would like to make the matrix symmetric.

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

As a newcomer from Matlab world, I can't get it working without for loops. In MATLAB it was easy:

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

W = max(A,A')

where A' is matrix transposition and the max() function takes care to make the W matrix which will be symmetric.

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

Is there an elegant way to do so in Python as well?

有没有一种优雅的方式在Python中这样做?

EXAMPLE The sample A matrix is:

示例样本A矩阵是:

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

The desired output matrix W is:

期望的输出矩阵W是:

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

2 个解决方案

#1


13  

Found a following solution which works for me:

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

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

#2


1  

For what it is worth, using the MATLAB's numpy equivalent you mentioned is more efficient than the link @plonser added.

对于它的价值,使用你提到的MATLAB的numpy等价物比@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

Timing for larger matrices can be done similarly:

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

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

And with N = 1000

并且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

#1


13  

Found a following solution which works for me:

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

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

#2


1  

For what it is worth, using the MATLAB's numpy equivalent you mentioned is more efficient than the link @plonser added.

对于它的价值,使用你提到的MATLAB的numpy等价物比@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

Timing for larger matrices can be done similarly:

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

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

And with N = 1000

并且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