【问题标题】:Cope with different slicing-behaviour in scipy.sparse and numpy在 scipy.sparse 和 numpy 中处理不同的切片行为
【发布时间】:2019-07-22 11:08:21
【问题描述】:

设置

我知道 scipy 的 .sparse-module 中的稀疏矩阵与 numpy-arrays 不同。另外,我知道像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])

【问题讨论】:

  • 您可以使用matrix[:, 3:4] 获得类似sparse_matrix[:, 3] 的输出。
  • 稀疏矩阵就像np.matrix。像这样的索引返回一个总是 2d 的矩阵。
  • @WarrenWeckesser:我更新了我的问题以澄清这一点(抱歉,这令人困惑):sparse_matrix 的输出应与matrix 相同,而不是相反。
  • "sparse_matrix 上的切片应与matrix 具有相同的输出"。问题是matrix 是一个二维numpy 数组,所以matrix[:, 3] 是一个一维 数组。 sparse_matrix 是一个稀疏矩阵对象,对一个稀疏矩阵进行切片总是会返回另一个稀疏矩阵,而这些对象总是是二维的。你必须做类似sparse_matrix[:, 3].A.ravel()的事情。

标签: python arrays numpy scipy sparse-matrix


【解决方案1】:
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)的行为。稀疏矩阵总是 2d。

这个矩阵的密集阵列显示:

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 在 1d ndarray 中添加了前导大小 1 维度。

【讨论】:

  • 感谢您的澄清。虽然不能直接按预期对稀疏矩阵进行切片,但有点难过。
  • 您可能想了解矩阵的存储方式。你lil 是按行存储的。选择一行相当简单。甚至还有类似“视图”的方法。但是选择一列意味着跨行查找值。同样,csr 针对行访问进行了优化,而它的转置更直接地给出了列。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-17
  • 1970-01-01
  • 2015-01-19
  • 2019-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多