2016-11-21 115 views
0

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

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,这是不高效的。任何人都可以证实这一点,并有解决方案

回答

0

警告告诉您,在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需要时间。

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

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

设置行v列并没有太大的差别。

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 
+0

感谢您的回答,但通常csc格式应该是最佳的这种列切片操作不是? 我不明白为什么它会改变这个特定操作的内部稀疏结构 –

+1

如果它改变了非标准的数量,它会改变稀疏性。这不是'csc' v'csr'问题。在我的计时中,是否复制了一行或一列是没有关系的。但随意做你自己的时间。 – hpaulj