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

Python 有没有更快的方法从scipy.sparse.dok_矩阵中提取行/列子矩阵?,python,numpy,sparse-matrix,Python,Numpy,Sparse Matrix,我正在使用numpy的dok_矩阵稀疏矩阵,并且,以Matlab风格,需要提取行或列的块,例如 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 ro

我正在使用
numpy
dok_矩阵
稀疏矩阵,并且,以Matlab风格,需要提取行或列的块,例如

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
问题:

  • 如果
    rowindsined
    包含大多数原始索引,是否有更快的方法提取子矩阵
  • 如果相反,即
    rowindsined
    相对较短,该怎么办
  • 如果我提取列而不是行,那么#1或2的答案会改变吗
  • 我应该将
    X
    转换为不同的稀疏格式吗?它没有任何方便的结构,即它不是块或对角线等。我还需要执行其他块操作,如“查找N以上1个数的所有行/列”、“查找行/列k1和k2中公共0/1的数”等

  • 如果有关系,我将在一个有11GB内存的RedHat 6盒上运行此程序

    构建一个样本随机矩阵:

    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>
    
    因此,转换到
    csr
    可以很好地提高速度,特别是如果您可以在执行其他操作之前执行一次转换

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

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

    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
    
    [182]中的
    :timeit M[np.arange(80),:]
    100个回路,最佳3个:每个回路15.1毫秒
    
    在[183]:timeit M[np.arange(100)中,您是否使用一个大的零向量进行索引?为什么?您是否尝试过转换为其他格式(很容易)并尝试过它们的速度?不,
    np.zeros(22000)
    操作只是预先分配数组,因为我知道它会有多长
    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
    
    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