【问题标题】:Re-ordering of the rows and columns in a CSR matrix重新排序 CSR 矩阵中的行和列
【发布时间】:2020-06-04 16:47:38
【问题描述】:

我有一个稀疏 csr 格式的矩阵,例如:

from scipy.sparse import csr_matrix
import numpy as np
row = np.array([0, 0, 1, 2, 2, 2])
col = np.array([0, 2, 2, 0, 1, 2])
data = np.array([1, 2, 3, 4, 5, 6])
M  = csr_matrix((data, (row, col)), shape=(3, 3)) 
M.A = 
array([[1, 0, 2],
       [0, 0, 3],
       [4, 5, 6]])

我正在使用以下方法对索引为 [2,0,1] 的矩阵重新排序:

order = np.array([2,0,1])
M = M[order,:]
M = M[:,order]
M.A
array([[6, 4, 5],
       [2, 1, 0],
       [3, 0, 0]])

这种方法有效,但对于我真正的 csr_matrix 是不可行的,它的大小为16580746 X 1672751804 并导致内存错误。 我采取了这样的另一种方法:

edge_list = zip(row,col,dat)
index = dict(zip(order, range(len(order))))
all_coeff = zip(*((index[u], index[v],d) for u,v,d in edge_list if u in index and v in index))
new_row,new_col,new_data = all_coeff
n = len(order)
graph  = csr_matrix((new_data, (new_row, new_col)), shape=(n, n))

这也有效,但是对于大型稀疏矩阵也陷入了内存错误的陷阱。有什么建议可以有效地做到这一点?

【问题讨论】:

    标签: python scipy networkx sparse-matrix adjacency-matrix


    【解决方案1】:

    让我们聪明地思考。

    您为什么不直接处理您在开始时提供的行和列索引,而不是重新排序矩阵?

    例如,您可以通过以下方式替换行索引:

    [0, 0, 1, 2, 2, 2]
    

    到:

    [2, 2, 0, 1, 1, 1]
    

    还有你的列索引,来自:

    [0, 2, 2, 0, 1, 2]
    

    到:

    [2, 1, 1, 2, 0, 1]
    

    【讨论】:

    • 好的,我了解行列替换,但是如何更新数据呢?
    • @MohanTimilsina 你应该重新加载你的数据。您可以从 csr 矩阵中获取数据、行和列索引(有称为索引、数据等的参数)。获得后,您可以随意更改索引
    【解决方案2】:

    我发现使用矩阵运算是最有效的。这是一个将行和/或列排列为指定顺序的函数。如果您愿意,可以修改它以交换两个特定的行/列。

    from scipy import sparse
    
    def permute_sparse_matrix(M, new_row_order=None, new_col_order=None):
        """
        Reorders the rows and/or columns in a scipy sparse matrix 
            using the specified array(s) of indexes
            e.g., [1,0,2,3,...] would swap the first and second row/col.
        """
        if new_row_order is None and new_col_order is None:
            return M
        
        new_M = M
        if new_row_order is not None:
            I = sparse.eye(M.shape[0]).tocoo()
            I.row = I.row[new_row_order]
            new_M = I.dot(new_M)
        if new_col_order is not None:
            I = sparse.eye(M.shape[1]).tocoo()
            I.col = I.col[new_col_order]
            new_M = new_M.dot(I)
        return new_M
    

    【讨论】:

      猜你喜欢
      • 2016-03-25
      • 1970-01-01
      • 1970-01-01
      • 2019-11-10
      • 1970-01-01
      • 1970-01-01
      • 2019-08-09
      • 1970-01-01
      • 2014-06-02
      相关资源
      最近更新 更多