scipy csr_matrix:了解indptr

时间:2018-09-12 16:07:35

标签: python scipy sparse-matrix

每隔一段时间,我都会操纵csr_matrix,但是我总是忘记参数indicesindptr是如何一起工作以建立稀疏矩阵的。

我正在寻找一个清晰直观的解释,说明在使用符号indptr定义稀疏矩阵时dataindicescsr_matrix((data, indices, indptr), [shape=(M, N)])参数如何相互作用。

我从scipy documentation看到data参数包含所有非零数据,而indices参数包含与该数据相关的列(因此{{ 1}}等于文档中给出的示例中的indices。但是我们如何清楚地解释col参数呢?

4 个答案:

答案 0 :(得分:9)

也许这种解释可以帮助理解这个概念(至少我是这样理解它的原理)

indptr参数指向稀疏矩阵中的每一行:

  • 通过指向indices的正确元素来填充哪一列
  • 通过指向data的正确元素来填充什么数据

这是通过以下推理完成的:

  1. 如果稀疏矩阵具有 M 行,则indptr参数具有 M + 1 个元素
  2. 对于行 i [indptr[i]:indptr[i+1]]给出indicesdata中的元素,以填充该行的稀疏矩阵。换句话说,[indptr[i]:indptr[i+1]]返回与行 i 相对应的indicesdata中要采用的元素的索引。

因此indptr中给出的数字必然会增加,因为它可以查询dataindices参数以填充稀疏矩阵。

编辑:添加了以下图像,希望它使内容更清晰。 indices包含存储非零值的列的信息,而data包含非零实际值的信息。 indptr映射与indicesdata中的每个元素关联的行。

enter image description here

答案 1 :(得分: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]])

在以上scipy文档中的示例中。

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

  • 索引数组提供每个非零数据点的列号。

  • 例如:-col [0]用于数据中的第一个元素,即1,col [2]用于数据中的第二个元素,即2,依此类推,直到最后一个数据元素,因此数据数组的大小并且索引数组相同。

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

  • 例如:-indptr的第一个元素为0表示存在于data [0]处的row [0]的第一个元素,即'1',indptr的第二个元素为2指示行中的第一个元素出现在数据[2](即元素“ 3”和indptr的第三个元素)上的[1]为3,表示行[2]的第一个元素在数据[3](即“ 4”)上。

  • 希望您明白这一点。

答案 2 :(得分:0)

当然,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)

答案 3 :(得分:0)

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

我们使用:

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