使 numpy ndarray 矩阵对称

问题描述 投票:0回答:4

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

作为 Matlab 世界的新手,如果没有 for 循环,我就无法让它工作。在 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
python matlab numpy matrix
4个回答
37
投票

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

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

12
投票

使用 NumPy

tril
triu
函数,如下所示。它本质上是将下三角形中的元素“镜像”到上三角形中。

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
的行为略有不同。上三角形中的所有元素都会被覆盖,无论它们是否是最大值。这意味着它们可以是任何值(例如
nan
inf
)。


3
投票

就其价值而言,使用您提到的 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

0
投票

可以得到对称正定

import pandas as pd
from sklearn.datasets import make_spd_matrix    # spd - symmetric positive-definite matrix

spd = make_spd_matrix(n_dim=3, random_state=1)
print(pd.DataFrame(spd))
© www.soinside.com 2019 - 2024. All rights reserved.