我想对称地排列稀疏矩阵,以相同的方式排列行和列。例如,我想旋转行和列,这需要:
1 2 3
0 1 0
0 0 1
到
1 0 0
0 1 0
2 3 1
在Octave或MATLAB中,可以使用矩阵索引简洁地做到这一点:
A = sparse([1 2 3; 0 1 0; 0 0 1]);
perm = [2 3 1];
Aperm = A(perm,perm);
我对使用NumPy / SciPy在Python中执行此操作感兴趣。这是一个尝试:
#!/usr/bin/env python
import numpy as np
from scipy.sparse import csr_matrix
row = np.array([0, 0, 0, 1, 2])
col = np.array([0, 1, 2, 1, 2])
data = np.array([1, 2, 3, 1, 1])
A = csr_matrix((data, (row, col)), shape=(3, 3))
p = np.array([1, 2, 0])
#Aperm = A[p,p] # gives [1,1,1], the permuted diagonal
Aperm = A[:,p][p,:] # works, but more verbose
是否存在一种更干净的方法来完成矩阵的这种对称排列?
(我对简洁语法比对性能更感兴趣)
答案 0 :(得分:3)
在MATLAB
中A(perm,perm)
是一个块操作。在numpy
中,A[perm,perm]
选择对角线上的元素。
A[perm[:,None], perm]
是块索引。 MATLAB对角线需要使用sub2ind
之类的东西。一个简洁,另一个简洁,v.v。
实际上,numpy
在两种情况下都使用相同的逻辑。它“广播”一个索引相对于另一个索引,在对角线情况下针对(n,)
对(n,)
,对块情况下(n,1)
针对(1,n)
。结果为(n,)
和(n,n)
形。
此numpy
索引也可用于稀疏矩阵,尽管它的速度并不快。实际上,它使用矩阵乘法来进行这种索引-使用基于索引(可能为2,M*A*M.T
)的“提取器”矩阵。
MATLAB有关置换矩阵的文档:
https://www.mathworks.com/help/matlab/math/sparse-matrix-operations.html#f6-13070