Scipy:稀疏CSR基质的对称排列



我想以相同的方式对称地置入稀疏矩阵,置换行和列。例如,我想旋转行和列,这是:

 1     2     3
 0     1     0
 0     0     1

to

 1     0     0
 0     1     0
 2     3     1

在八度或matlab中,可以用矩阵索引简洁地执行此操作:

A = sparse([1 2 3; 0 1 0; 0 0 1]);
perm = [2 3 1];
Aperm = A(perm,perm);

我有兴趣在python上使用numpy/scipy。这是一个尝试:

#!/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

是否有一种更干净的方法来完成矩阵的这种对称置换?

(我对简洁语法比对性能更感兴趣)

在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

最新更新