簡體   English   中英

scipy csr_matrix:了解indptr

[英]scipy csr_matrix: understand indptr

每隔一段時間,我就會操作一個csr_matrix ,但我總是忘記參數indicesindptr如何一起工作來構建一個稀疏矩陣。

我正在尋找關於在使用符號csr_matrix((data, indices, indptr), [shape=(M, N)])定義稀疏矩陣時indptr如何與dataindices參數交互的清晰直觀的解釋。

我可以從scipy 文檔中看到, data參數包含所有非零數據, indices參數包含與該數據關聯的列(因此, indices等於文檔中給出的示例中的col )。 但是我們如何才能清楚地解釋indptr參數呢?

也許這個解釋可以幫助理解這個概念:

  • data是一個包含稀疏矩陣的所有非零元素的數組。
  • indices是一個數組,將data每個元素映射到稀疏矩陣中的列。
  • indptr然后將dataindices的元素映射到稀疏矩陣的行。 這是通過以下推理完成的:

    1. 如果稀疏矩陣有M行,則indptr是一個包含M+1 個元素的數組
    2. 對於第i行, [indptr[i]:indptr[i+1]]返回要從第i行對應的dataindices獲取的元素indices 因此,假設indptr[i]=kindptr[i+1]=l ,對應於行i的數據將是data[k:l]indices[k:l] 這是棘手的部分,我希望下面的例子有助於理解它。

編輯:我取代了的數字data由字母,以避免混淆在下面的例子。

在此處輸入圖片說明

注意:在值indptr必然增加,因為在下一小區indptr (下一行)的參照下一個值dataindices對應於該行。

當然,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)
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'。

  • 希望你明白這一點。

由於這是一個稀疏矩陣,這意味着與整個元素($m \\times n$)相比,矩陣中的非零元素相對很少。

我們用 :

  • data存儲所有非零元素,從左到右,從上到下
  • indices來存儲所有列索引為這些數據的
  • indptr[i]:indptr[i+1]表示data域中的切片以查找row[i]的所有非零元素

在這個例子中:

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非零數據元素的數量,從第三行的開始到結束。

將 indptr 中的值視為在預壓縮(稀疏)格式的特定行開始之前已經通過的非零元素的數量 這是一個難以理解的問題,但下面的示例應該可以闡明。

import numpy as np
from scipy.sparse import csr_matrix

array_for_csr = np.array([[2, 0, 19, 5],
                          [8, 0, 0, 1],
                          [0, 0, 0, 0],
                          [4, 6, 6, 0]])
matrix = csr_matrix(array_for_csr)
print(matrix)
"""
(0, 0)  2
(0, 2)  19
(0, 3)  5
(1, 0)  8
(1, 3)  1
(3, 0)  4
(3, 1)  6
(3, 2)  6
"""
print(matrix.indices)
# [0 2 3 0 3 0 1 2]
print(matrix.indptr)
# [0 3 5 5 8]

前任。

indptr[0] = 0 因為矩陣中的 0 個值在預壓縮矩陣的第一行開始之前已經傳遞(沒有值傳遞,因為我們還沒有開始遍歷矩陣)

indptr[1] = 3 因為矩陣中的 3 個值在預壓縮矩陣的第 2 行開始之前已經傳遞(值 2、19、5)

indptr[2] = 5 因為在預壓縮矩陣的第 3 行開始之前已經傳遞了矩陣中的 5 個值(值 2、19、5、8、1)

indptr[3] = 5 因為矩陣中的 5 個值在預壓縮矩陣的第 4 行開始之前已經傳遞(因為預壓縮矩陣第 4 行中的所有值均為零)

indptr[4] = 8 因為矩陣中的 8 個值在預壓縮矩陣的第 5 行開始之前已經過去(indptr 數組中的最后一個值將始終等於非零值的數量預壓縮(稀疏)矩陣

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM