应对 scipy.sparse 和 numpy 中的不同切片行为

Cope with different slicing-behaviour in scipy.sparse and numpy

设置

我知道 scipy 的 .sparse 模块中的稀疏矩阵不同于 numpy 数组。另外,我知道 here 等关于稀疏数组切片的问题。无论如何,这个问题和大多数其他问题都与切片的性能有关。

我的问题是关于如何处理它们不同的切片行为。让我们创建一个示例:

import numpy as np
from scipy import sparse

matrix = np.asarray([[0,0,0,1], [1,1,0,0], [1,0,1,0], [1,0,0,1], [1,0,0,1], [1,0,0,1]])
sparse_matrix = sparse.lil_matrix(matrix) # Or another format like .csr_matrix etc.

鉴于此设置,应用相同的切片会产生不同的输出:

matrix[:, 3]
# Output: 
# array([ True, False, False,  True,  True,  True], dtype=bool)

sparse_matrix[:, 3]
# Output:
# matrix([[ True],
#        [False],
#        [False],
#        [ True],
#        [ True],
#        [ True]], dtype=bool)

问题

这有点令人失望,因为我还需要第一个输出应用于第二种情况。正如一开始所说,我知道使用 sparse_matrix.A 等会给我想要的结果。无论如何,将稀疏矩阵转换为数组与稀疏矩阵的初始用例相矛盾。

那么是否有可能在不将 sparse-matrix 转换为数组的情况下实现相同的切片结果?

编辑: 为澄清起见,因为我的问题可能与此有关: sparse_matrix 上的切片应具有与 matrix 相同的输出,这意味着 sparse_matrix[:, 3] 之类的内容应输出 ([ True, False, False, True, True, True])

In [150]: arr = np.asarray([[0,0,0,1], [1,1,0,0], [1,0,1,0], [1,0,0,1], [1,0,0,1], [1,0,0,1]]) 
     ...: M = sparse.lil_matrix(arr) # Or another format like .csr_matrix etc. 

ndarray 上的标量索引将维度减少一:

In [151]: arr[:,3]                                                                                           
Out[151]: array([1, 0, 0, 1, 1, 1])

它不会改变稀疏矩阵的维数。

In [152]: M[:,3]                                                                                             
Out[152]: 
<6x1 sparse matrix of type '<class 'numpy.int64'>'
    with 4 stored elements in LInked List format>

此行为类似于 np.matrix 子类(和 MATLAB)的行为。稀疏矩阵总是二维的。

该矩阵的密集数组显示:

In [153]: M[:,3].A                                                                                           
Out[153]: 
array([[1],
       [0],
       [0],
       [1],
       [1],
       [1]], dtype=int64)

np.matrix 显示:

In [154]: M[:,3].todense()                                                                                   
Out[154]: 
matrix([[1],
        [0],
        [0],
        [1],
        [1],
        [1]], dtype=int64)

np.matrix 有一个 A1 属性 生成一维数组(它转换为 ndarray 并应用 ravel):

In [155]: M[:,3].todense().A1                                                                                
Out[155]: array([1, 0, 0, 1, 1, 1], dtype=int64)

ravelsqueeze 和标量索引都是减少 ndarray 维度的方法。但它们不能直接在 np.matrix 或稀疏矩阵上工作。

二维稀疏矩阵的另一个例子:

In [156]: sparse.lil_matrix(arr[:,3])                                                                        
Out[156]: 
<1x6 sparse matrix of type '<class 'numpy.int64'>'
    with 4 stored elements in LInked List format>
In [157]: _.A                                                                                                
Out[157]: array([[1, 0, 0, 1, 1, 1]], dtype=int64)

注意 [[...]]sparse 已将前导尺寸 1 尺寸添加到 1d ndarray