将列放入空稀疏矩阵

Posted

技术标签:

【中文标题】将列放入空稀疏矩阵【英文标题】:putting column into empty sparse matrix 【发布时间】:2016-11-21 14:47:34 【问题描述】:

我想将一个稀疏柱状矩阵中的一列放入另一个(空)稀疏柱状矩阵。 玩具代码:

import numpy as np
import scipy.sparse
row = np.array([0, 2, 0, 1, 2])
col = np.array([0, 0, 2, 2, 2])
data = np.array([1, 2, 4, 5, 6])
M=scipy.sparse.csc_matrix((data, (row, col)), shape=(3, 3))
E=scipy.sparse.csc_matrix((3, 3)) #empty 3x3 sparse matrix

E[:,1]=M[:,0]

但是我收到警告:

SparseEfficiencyWarning:更改 csc_matrix 的稀疏结构是>昂贵的。 lil_matrix 更高效。

这个警告让我担心在这个过程中矩阵被转换成另一种格式,然后又回到 csc,这样效率不高。任何人都可以确认这一点并有解决方案吗?

【问题讨论】:

【参考方案1】:

警告告诉您在 csc(或 csr)格式矩阵中设置新值的过程很复杂。这些格式不是为像这样的简单更改而设计的。 lil 格式旨在让这种更改变得快速而轻松,尤其是在一行中进行更改。

请注意,coo 格式甚至没有实现这种索引。

它不会转换为 lil 并返回,但这实际上可能是一种更快的方法。我们必须做一些时间测试。

In [679]: %%timeit E=sparse.csr_matrix((3,3))
     ...: E[:,1] = M[:,0]
     ...: 
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
  SparseEfficiencyWarning)
1000 loops, best of 3: 845 µs per loop
In [680]: %%timeit E=sparse.csr_matrix((3,3))
     ...: E1=E.tolil()
     ...: E1[:,1] = M[:,0]
     ...: E=E1.tocsc()
     ...: 
The slowest run took 4.22 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 1.42 ms per loop

In [682]: %%timeit E=sparse.lil_matrix((3,3))
     ...: E[:,1] = M[:,0]
     ...: 
1000 loops, best of 3: 804 µs per loop
In [683]: %%timeit E=sparse.lil_matrix((3,3));M1=M.tolil()
     ...: E[:,1] = M1[:,0]
     ...: 
     ...: 
1000 loops, best of 3: 470 µs per loop

In [688]: timeit M1=M.tolil()
The slowest run took 4.10 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 248 µs per loop

请注意,使用lil(两侧)执行分配比使用csc 执行分配快 2 倍。但是与lil 之间的转换需要时间。

警告与否,您正在做的是最快的 - 一次性操作。但如果您需要反复执行此操作,请尝试找到更好的方法。

==================

设置行和列没有太大区别。

In [835]: %%timeit E=sparse.csc_matrix((3,3))
     ...: E[:,1]=M[:,0]
  SparseEfficiencyWarning)
1000 loops, best of 3: 1.89 ms per loop

In [836]: %%timeit E=sparse.csc_matrix((3,3))
     ...: E[1,:]=M[0,:]    
  SparseEfficiencyWarning)
1000 loops, best of 3: 1.91 ms per loop

【讨论】:

感谢您的回答,但通常 csc 格式对于这样的列切片操作应该是最佳的,不是吗?我不明白为什么它会在内部改变这个特定操作的稀疏结构 如果它改变了非零的数量,它改变了稀疏性。这不是csc v csr 问题。在我的时间里,我复制一行还是一列并不重要。但请随意安排自己的时间。

以上是关于将列放入空稀疏矩阵的主要内容,如果未能解决你的问题,请参考以下文章

以对数方式缩放(应用函数?)稀疏矩阵

pyspark:将稀疏局部矩阵转换为 RDD

稀疏矩阵乘法 · Sparse Matrix Multiplication

稀疏矩阵及其压缩格式

多维数组-矩阵的压缩存储- 稀疏矩阵(一)

稀疏矩阵的压缩与还原