scipy几种稀疏矩阵表示

scipy.sparse里面有几种稀疏矩阵的表示:

  1. lil_matrix(row-based linked list matrix)
  2. dok_matrix(dictionary of keys matrix)
  3. coo_matrix(coordinate matrix)

lil_matrix实现上是基于row的链表实现,在创建阶段最好按照row的顺序插入或者是修改。适合增量构建。 dok_matrix是认为坐标是(i,j)是key, 矩阵元素是value, 使用字典的方式进行存储。适合增量构建。 coo_matrix有三个数组,row,col, data. 其中data[i] = matrix[row[i], col[i]]. 不太容易增量构建,适合批量构建。

在coo_matrix的基础上进行压缩,根据压缩方式有几种矩阵表示:

  1. csr_matrix. (compressed sparse row matrix). 针对行做压缩
  2. csc_matrix. (compressed sparse column matrix). 针对列做压缩
  3. bsr_matrix. 在csr_matrix基础上的优化,针对局部比较稠密的矩阵做压缩

关于这几种matrix的存储和运算优劣可以参考scipy文档


假设我们有个矩阵如下:

array([[1., 2., 3., 0., 0.],
       [0., 4., 5., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]])

m2 = scipy.sparse.coo_matrix(m.toarray())
m3 = m2.tocsr()
m4 = m2.tocsc()

coo_matrix矩阵比较好理解

m2.data
Out[114]: array([1., 2., 3., 4., 5.])

m2.row
Out[115]: array([0, 0, 0, 1, 1], dtype=int32)

m2.col
Out[116]: array([0, 1, 2, 1, 2], dtype=int32)

csr_matrix矩阵里面有 `data`, `indptr`, `indices` 三个变量共同定位,其中row ith的数据是 `data[indptr[i]:indptr[i+1]]`, 对应的colum是 `indices[indptr[i]:indptr[i+1]`. 所以假设有N个row的话,那么indptr的大小是N+1. csc_matrix和csr_matrix相对应,只不过是通过column来定位.

m3.data
Out[117]: array([1., 2., 3., 4., 5.])

m3.indptr
Out[118]: array([0, 3, 5, 5, 5, 5], dtype=int32)

m3.indices
Out[119]: array([0, 1, 2, 1, 2], dtype=int32)

m4.data
Out[120]: array([1., 2., 4., 3., 5.])

m4.indptr
Out[121]: array([0, 1, 3, 5, 5, 5], dtype=int32)

m4.indices
Out[122]: array([0, 0, 1, 0, 1], dtype=int32)

几种matrix之间相互转换的时间也是不对称的,从csc, csr -> coo转换的时间,相比coo->csc, csr的时间更短。所以如果只能使用一种中间存储格式的话,尽可能使用csc,csr而不是coo.

mat_csr
<4609357x137344 sparse matrix of type '<type 'numpy.float32'>'
        with 42015431 stored elements in Compressed Sparse Row format>

%timeit mat_csr.tocoo()
1 loop, best of 3: 611 ms per loop

%timeit mat_coo.tocsr()
The slowest run took 5.54 times longer than the fastest. This could mean that an intermediate result is being cached.
1 loop, best of 3: 5.1 s per loop