【问题标题】:scipy csr_matrix: understand indptrscipy csr_matrix:了解 indptr
【发布时间】:2023-03-17 13:24:01
【问题描述】:

每隔一段时间,我都会操作csr_matrix,但我总是忘记参数indicesindptr 是如何协同工作来构建稀疏矩阵的。

在使用符号csr_matrix((data, indices, indptr), [shape=(M, N)]) 定义稀疏矩阵时,我正在寻找关于indptr 如何与dataindices 参数交互的清晰直观的解释。

我可以从scipy documentation 看到data 参数包含所有非零数据,indices 参数包含与该数据关联的列(因此,indices 等于@987654332 @ 在文档中给出的示例中)。但是我们如何才能清楚地解释indptr参数呢?

【问题讨论】:

  • 查看lil 等效项可能会有所帮助。 @Tanguy 描述的连续切片 M.indices[indptr[i]:indptr[i+1]] 对应于 lil rows 数组中的列表。

标签: python scipy sparse-matrix


【解决方案1】:

在这个例子中:

indptr = np.array([0, 2, 3, 6])
indices = np.array([0, 2, 2, 0, 1, 2])
data = np.array([1, 2, 3, 4, 5, 6])
csr_matrix((data, indices, indptr), shape=(3, 3)).toarray()
array([[1, 0, 2],
      [0, 0, 3],
      [4, 5, 6]])

要阅读indptr,请执行此操作-

  • 忽略indptr[0] = 0
  • indptr[1] = 2 告诉非零数据元素的数量,直到第一行的末尾
  • indptr[2] = 3 告诉非零数据元素的数量,从开始到第二行结束。
  • indptr[3] = 6 告诉非零数据元素的数量,从开始到第三行结束。

【讨论】:

    【解决方案2】:

    由于这是一个稀疏矩阵,这意味着与整个元素相比,矩阵中的非零元素相对很少($m \times n$)。

    我们使用:

    • data 存储所有非零元素,从左到右,从上到下
    • indices 存储每个数据的所有列索引
    • indptr[i]:indptr[i+1] 表示 data 字段中的切片以查找 row[i] 的所有非零元素

    【讨论】:

      【解决方案3】:
      indptr = np.array([0, 2, 3, 6])
      indices = np.array([0, 2, 2, 0, 1, 2])
      data = np.array([1, 2, 3, 4, 5, 6])
      csr_matrix((data, indices, indptr), shape=(3, 3)).toarray()
      array([[1, 0, 2],
            [0, 0, 3],
            [4, 5, 6]])
      

      上面的例子来自 scipy 文档。

      • 数据数组包含按行遍历的稀疏矩阵中存在的非零元素。

      • 索引数组给出每个非零数据点的列号。

      • 例如:-col[0] 表示数据中的第一个元素,即 1,col[2] 表示数据中的第二个元素,即 2,依此类推,直到最后一个数据元素,所以数据数组的大小和索引数组是一样的。

      • indptr 数组基本上表示行的第一个元素的位置。它的大小比行数大一。

      • 例如:- indptr 的第一个元素是 0,表示存在于 data[0] 的 row[0] 的第一个元素,即“1”,indptr 的第二个元素是 2,表示 row[1] 中的第一个元素它存在于 data[2] 即元素 '3' 和 indptr 的第三个元素是 3 表示 row[2] 的第一个元素在 data[3] 即'4'。

      • 希望你明白这一点。

      【讨论】:

        【解决方案4】:

        也许这个解释可以帮助理解这个概念:

        • data 是一个包含稀疏矩阵的所有非零元素的数组。
        • indices 是一个数组,将data 中的每个元素映射到稀疏矩阵中的列。
        • indptr 然后将dataindices 的元素映射到稀疏矩阵的行。这是通过以下推理完成的:

          1. 如果稀疏矩阵有 M 行,indptr 是一个包含 M+1 个元素的数组
          2. 对于行 i[indptr[i]:indptr[i+1]] 返回要从与行 i 对应的 dataindices 获取的元素的索引。所以假设indptr[i]=kindptr[i+1]=l,对应行i 的数据将是data[k:l] 在列indices[k:l]。这是棘手的部分,我希望下面的示例有助于理解它。

        编辑:我将data 中的数字替换为字母以避免在以下示例中混淆。

        注意:indptr 中的值必然会增加,因为indptr(下一行)中的下一个单元格是指与该行对应的dataindices 中的下一个值。

        【讨论】:

        • 感谢您试图说清楚,但仍然没有.. 您能否举一个 M 的示例,然后从一行中执行第 2 点,解释 indices 和 @987654343 中的哪些值@ 它来了?我试图遵循一个例子,但我没有得到它。
        • 我花了一些时间来理解这一点(但比我必须自己研究它要短得多),但我现在明白了。让我绊倒的部分是数据的连续值。一直认为这些值代表了列。如果它们是随机值,我认为这将有助于读者更快地理解。不过很棒。谢谢。
        • @ivankeller:将您的问题更新为编辑后的示例/图片:“indptr 的最后一个元素不应该是 10 而不是 11?” --> 否,因为在 python 中对数据结构进行子集时未选择范围中的最后一个元素(例如data[l] 不包含在data[k:l] 中)。
        • @spacedustpi:我用字母替换了data 中的值,希望能避免进一步混淆。关于你关于空行的问题,@a-nadjar 举了一个例子。如果第 i 行为空,则 indptr 的第 i 值等于第 i+1 值,因此子集范围为[indptr[i]:indptr[i+1]]dataindices 不返回任何值。
        • 一张图片值一千字。谢谢!
        【解决方案5】:

        当然,indptr 中的元素是升序排列的。 但是如何解释 indptr 行为呢?简而言之,直到 indptr 内的元素相同或不增加,您可以跳过稀疏矩阵的行索引。

        以下示例说明了对 indptr 元素的上述解释:

        示例 1) 想象这个矩阵:

        array([[0, 1, 0],
               [8, 0, 0],
               [0, 0, 0],
               [0, 0, 0],
               [0, 0, 7]])
        
        
        mat1 = csr_matrix(([1,8,7], [1,0,2], [0,1,2,2,2,3]), shape=(5,3))
        mat1.indptr
        # array([0, 1, 2, 2, 2, 3], dtype=int32)
        mat1.todense()  # to get the corresponding sparse matrix
        

        示例2)数组到CSR_matrix(稀疏矩阵已经存在的情况):

        arr = np.array([[0, 0, 0],
                        [8, 0, 0],
                        [0, 5, 4],
                        [0, 0, 0],
                        [0, 0, 7]])
        
        
        mat2 = csr_matrix(arr))
        mat2.indptr
        # array([0, 0, 1, 3, 3, 4], dtype=int32)
        mat2.indices
        # array([0, 1, 2, 2], dtype=int32)
        mat.data
        # array([8, 5, 4, 7], dtype=int32)
        

        【讨论】:

          猜你喜欢
          • 2022-01-26
          • 1970-01-01
          • 2014-10-22
          • 2020-02-01
          • 2020-05-31
          • 2015-08-02
          • 2016-01-21
          • 2023-03-31
          • 2018-06-25
          相关资源
          最近更新 更多