如何从巨大的(scipy.sparse)矩阵计算对角度矩阵?

时间:2012-01-18 05:44:02

标签: python numpy scipy sparse-matrix

给定一个100万维的二次矩阵,我想计算对角度矩阵。

对角度矩阵定义为对角矩阵,每行的非零值计数为。

矩阵,我们称之为A格式为scipy.sparse.csr_matrix

如果我的机器有足够的功率我会做的

diagonal_degrees = []
for row in A:
    diagonal_degrees.append(numpy.sum(row!=0))

我甚至试过了,但结果是

ValueError: array is too big.

所以我试图利用scipy的稀疏结构。我想到了这个方式:

diagonal_degrees = []
CSC_format = A.tocsc() # A is in scipys CSR format.
for i in range(CSC_format.shape[0]):
    row = CSC_format.getrow(i)
    diagonal_degrees.append(numpy.sum(row!=0))

我有两个问题:

  1. 有没有更有效的方式,我可能忽略了?
  2. docs of scipy sparse state
  3.   

    CSR,CSC和COO格式之间的所有转换都是高效的线性时间操作。

    为什么我会得到

    SparseEfficiencyWarning: changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
    

    从CSR更改为CSC?

1 个答案:

答案 0 :(得分:4)

如果您只需要计算非零元素,那么nonzero方法可能很有用。

确切代码(在Joe Kingtonmatehat的帮助下):

diag_deg, _ = np.histogram(x.nonzero()[0], np.arange(x.shape[0]+1))

# generating a diagonal matrix with diag_deg
dim = x.shape[0]
diag_mat = np.zeros((dim**2, ))
diag_mat[np.arange(0, dim**2, dim+1)] = diag_deg
diag_mat.reshape((dim, dim))

虽然对于大型数组(dim ~ 1 million),如Aufwind所述,np.zeros((dim**2, ))会给出异常:ValueError: Maximum allowed dimension exceeded。另一种解决方法是使用稀疏矩阵:

diag_mat = sparse.coo_matrix((dim, dim))
diag_mat.setdiag(diag_deg)