有没有更快的方法从scipy.sparse.dok_matrix中提取行/列子矩阵?

时间:2015-09-11 12:43:08

标签: python numpy sparse-matrix

我正在处理numpy的{​​{1}}稀疏矩阵,并且Matlab风格需要提取行或列的块,例如

dok_matrix

问题:

  1. 如果import numpy as np from scipy.sparse import dok_matrix # # Boolean data matrix X created here # print X.shape #(24000, 110000) # Size below is approx but shows I need need most of the original rows rowIndsINeed = np.zeros(22000) # # Populate rowIndsINeed here # Xsubmat = X[rowIndsINeed,] # this is slooooow 包含大部分原始索引,是否有更快的方法来提取子矩阵?
  2. 如果相反,即rowIndsINeed相对较短怎么办?
  3. 如果我提取列而不是行,#1或2的答案会改变吗?
  4. 我应该将rowIndsINeed转换为其他稀疏格式吗?它没有任何方便的结构,即它不是块或对角线等。我还需要进行其他块操作,例如"查找数字为1' s高于N&#34的所有行/列;,"在行/列k1和k2"中找到公共0' s / 1的数量;等。
  5. 如果重要的话,我在带有11GB RAM

    的RedHat 6盒子上运行它

1 个答案:

答案 0 :(得分:2)

构建一个样本随机矩阵:

In [130]: M=sparse.rand(100,100,.1,format='dok')
In [131]: M
Out[131]: 
<100x100 sparse matrix of type '<class 'numpy.float64'>'
    with 1000 stored elements in Dictionary Of Keys format>
In [132]: M[0,:]
Out[132]: 
<1x100 sparse matrix of type '<class 'numpy.float64'>'
    with 6 stored elements in Dictionary Of Keys format>

像你这样的指数:

In [133]: idx=np.zeros((80,),int)
In [134]: M[idx,]
Out[134]: 
<80x100 sparse matrix of type '<class 'numpy.float64'>'
    with 480 stored elements in Dictionary Of Keys format>

它返回了一个矩阵,其中包含80行第0行(80 * 6 = 480个非零元素)。

这听起来不太有用。

但是,让我们尝试一些时间:

In [142]: timeit M[idx,]
100 loops, best of 3: 13.2 ms per loop
In [143]: timeit M.tocsr()[idx,]
100 loops, best of 3: 2.33 ms per loop
In [144]: timeit M.tocsc()[idx,]
100 loops, best of 3: 2.87 ms per loop
In [145]: timeit M.tolil()[idx,]
100 loops, best of 3: 4.39 ms per loop
In [146]: %%timeit m1=M.tocsr()
   .....: m1[idx,]
   .....: 
1000 loops, best of 3: 691 µs per loop

因此转换为csr可以提高速度,尤其是在进行其他操作之前,您可以进行一次转换。

您可以为其他操作执行类似的测试。

如果您的目标是选择M的前80行:

In [182]: timeit M[np.arange(80),:]
100 loops, best of 3: 15.1 ms per loop
In [183]: timeit M[np.arange(100)<80,:]
100 loops, best of 3: 15 ms per loop
In [184]: timeit M[:80,:]
100 loops, best of 3: 5.63 ms per loop