scipy几种稀疏矩阵表示
scipy.sparse里面有几种稀疏矩阵的表示:
- lil_matrix(row-based linked list matrix)
- dok_matrix(dictionary of keys matrix)
- 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的基础上进行压缩,根据压缩方式有几种矩阵表示:
- csr_matrix. (compressed sparse row matrix). 针对行做压缩
- csc_matrix. (compressed sparse column matrix). 针对列做压缩
- 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