稀疏矩阵三元组 严蔚敏_Sparse稀疏矩阵主要存储格式总结
生活随笔
收集整理的這篇文章主要介紹了
稀疏矩阵三元组 严蔚敏_Sparse稀疏矩阵主要存储格式总结
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在數據科學和深度學習等領域會采用矩陣來存儲數據,但當矩陣較為龐大且非零元素較少時,運算效率和存儲有效率并不高。所以,一般情況我們采用Sparse稀疏矩陣的方式來存儲矩陣,來提高存儲和運算效率。下面將對SciPy中七種常見的存儲方式(COO/ CsR/ CSC/ BSR/ DOK/ LIL/ DIA)的概念和用法進行介紹和對比總結。
本文首發于個人博客,排版格式更加友好,歡迎訪問
稀疏矩陣簡介
稀疏矩陣
- 稀疏矩陣
- 具有少量非零項的矩陣 - Number of Non-Zero (NNZ) < 0.5
- (在矩陣中,若數值0的元素數目遠多于非0元素的數目,并且非0元素分布沒有規律)
- 矩陣的稠密度
- 非零元素的總數比上矩陣所有元素的總數為矩陣的稠密度。
壓縮存儲
存儲矩陣的一般方法是采用二維數組,其優點是可以隨機地訪問每一個元素,因而能夠容易實現矩陣的各種運算。
對于稀疏矩陣,它通常具有很大的維度,有時甚大到整個矩陣(零元素)占用了絕大部分內存
采用二維數組的存儲方法既浪費大量的存儲單元來存放零元素,又要在運算中浪費大量的時間來進行零元素的無效運算。因此必須考慮對稀疏矩陣進行壓縮存儲(只存儲非零元素)。
矩陣屬性
from scipy.sparse import csr_matrix### 共有屬性 mat.shape # 矩陣形狀 mat.dtype # 數據類型 mat.ndim # 矩陣維度 mat.nnz # 非零個數 mat.data # 非零值, 一維數組### COO 特有的 coo.row # 矩陣行索引 coo.col # 矩陣列索引### CSRCSCBSR 特有的 bsr.indices # 索引數組 bsr.indptr # 指針數組 bsr.has_sorted_indices # 索引是否排序 bsr.blocksize # BSR矩陣塊大小通用方法
import scipy.sparse as sp### 轉換矩陣格式 tobsr()、tocsr()、to_csc()、to_dia()、to_dok()、to_lil() mat.toarray() # 轉為array mat.todense() # 轉為dense # 返回給定格式的稀疏矩陣 mat.asformat(format) # 返回給定元素格式的稀疏矩陣 mat.astype(t) ### 檢查矩陣格式 issparse、isspmatrix_lil、isspmatrix_csc、isspmatrix_csr sp.issparse(mat)### 獲取矩陣數據 mat.getcol(j) # 返回矩陣列j的一個拷貝,作為一個(mx 1) 稀疏矩陣 (列向量) mat.getrow(i) # 返回矩陣行i的一個拷貝,作為一個(1 x n) 稀疏矩陣 (行向量) mat.nonzero() # 非0元索引 mat.diagonal() # 返回矩陣主對角元素 mat.max([axis]) # 給定軸的矩陣最大元素### 矩陣運算 mat += mat # 加 mat = mat * 5 # 乘 mat.dot(other) # 坐標點積resize(self, *shape) transpose(self[, axes, copy])稀疏矩陣分類
1. COO - coo_matrix
Coordinate Matrix 對角存儲矩陣
- 采用三元組(row, col, data)(或稱為ijv format)的形式來存儲矩陣中非零元素的信息
- 三個數組 row 、col 和 data 分別保存非零元素的行下標、列下標與值(一般長度相同)
- 故 coo[row[k]][col[k]] = data[k] ,即矩陣的第 row[k] 行、第 col[k] 列的值為 data[k]
- 當 row[0] = 1 , column[0] = 1 時, data[0] = 2 ,故 coo[1][1] = 2
- 當 row[3] = 0 , column[3] = 2 時, data[3] = 9 ,故 coo[0][3] = 9
適用場景
- 主要用來創建矩陣,因為coo_matrix無法對矩陣的元素進行增刪改等操作
- 一旦創建之后,除了將之轉換成其它格式的矩陣,幾乎無法對其做任何操作和矩陣運算
優缺點
①優點
- 轉換成其它存儲格式很快捷簡便(tobsr()、tocsr()、to_csc()、to_dia()、to_dok()、to_lil())
- 能與CSR / CSC格式的快速轉換
- 允許重復的索引(例如在1行1列處存了值2.0,又在1行1列處存了值3.0,則轉換成其它矩陣時就是2.0+3.0=5.0)
②缺點
- 不支持切片和算術運算操作
- 如果稀疏矩陣僅包含非0元素的對角線,則對角存儲格式(DIA)可以減少非0元素定位的信息量
- 這種存儲格式對有限元素或者有限差分離散化的矩陣尤其有效
實例化方法
- coo_matrix(D):D代表密集矩陣;
- coo_matrix(S):S代表其他類型稀疏矩陣
- coo_matrix((M, N), [dtype]):構建一個shape為M*N的空矩陣,默認數據類型是d,
- coo_matrix((data, (i, j)), [shape=(M, N)])):三元組初始化
- i[:] : 行索引
- j[:] : 列索引
- A[i[k], j[k]]=data[k]
特殊屬性
- data:稀疏矩陣存儲的值,是一個一維數組
- row:與data同等長度的一維數組,表征data中每個元素的行號
- col:與data同等長度的一維數組,表征data中每個元素的列號
代碼示例
# 數據 row = [0, 1, 2, 2] col = [0, 1, 2, 3] data = [1, 2, 3, 4]# 生成coo格式的矩陣 # <class 'scipy.sparse.coo.coo_matrix'> coo_mat = sparse.coo_matrix((data, (row, col)), shape=(4, 4), dtype=np.int)# coordinate-value format print(coo) ''' (0, 0) 1 (1, 1) 2 (2, 2) 3 (3, 3) 4 '''# 查看數據 coo.data coo.row coo.col# 轉化array # <class 'numpy.ndarray'> coo_mat.toarray() ''' array([[1, 0, 0, 0],[0, 2, 0, 0],[0, 0, 3, 4],[0, 0, 0, 0]]) '''2. CSR - csr_matrix
Compressed Sparse Row Matrix 壓縮稀疏行格式
- csr_matrix是按行對矩陣進行壓縮的
- 通過 indices, indptr,data 來確定矩陣。
- data 表示矩陣中的非零數據
- 對于第 i 行而言,該行中非零元素的列索引為 indices[indptr[i]:indptr[i+1]]
- 可以將 indptr 理解成利用其自身索引 i 來指向第 i 行元素的列索引
- 根據[indptr[i]:indptr[i+1]],我就得到了該行中的非零元素個數,如
- 若 index[i] = 3 且 index[i+1] = 3 ,則第 i 行的沒有非零元素
- 若 index[j] = 6 且 index[j+1] = 7 ,則第 j 行的非零元素的列索引為 indices[6:7]
- 得到了行索引、列索引,相應的數據存放在: data[indptr[i]:indptr[i+1]]
- 對于矩陣第 0 行,我們需要先得到其非零元素列索引
- 由 indptr[0] = 0 和 indptr[1] = 2 可知,第 0 行有兩個非零元素。
- 它們的列索引為 indices[0:2] = [0, 2] ,且存放的數據為 data[0] = 8 , data[1] = 2
- 因此矩陣第 0 行的非零元素 csr[0][0] = 8 和 csr[0][2] = 2
- 對于矩陣第 4 行,同樣我們需要先計算其非零元素列索引
- 由 indptr[4] = 3 和 indptr[5] = 6 可知,第 4 行有3個非零元素。
- 它們的列索引為 indices[3:6] = [2, 3,4] ,且存放的數據為 data[3] = 7 ,data[4] = 1 ,data[5] = 2
- 因此矩陣第 4 行的非零元素 csr[4][2] = 7 , csr[4][3] = 1 和 csr[4][4] = 2
適用場景
- 常用于讀入數據后進行稀疏矩陣計算,運算高效
優缺點
①優點
- 高效的稀疏矩陣算術運算
- 高效的行切片
- 快速地矩陣矢量積運算
②缺點
- 較慢地列切片操作(可以考慮CSC)
- 轉換到稀疏結構代價較高(可以考慮LIL,DOK)
實例化
- csr_matrix(D):D代表密集矩陣;
- csr_matrix(S):S代表其他類型稀疏矩陣
- csr_matrix((M, N), [dtype]):構建一個shape為M*N的空矩陣,默認數據類型是d,
- csr_matrix((data, (row_ind, col_ind)), [shape=(M, N)]))
- 三者關系:a[row_ind[k], col_ind[k]] = data[k]
- csr_matrix((data, indices, indptr), [shape=(M, N)])
- 第i行的列索引存儲在其中indices[indptr[i]:indptr[i+1]]
- 其對應值存儲在中data[indptr[i]:indptr[i+1]]
特殊屬性
- data :稀疏矩陣存儲的值,一維數組
- indices :存儲矩陣有有非零值的列索引
- indptr :類似指向列索引的指針數組
- has_sorted_indices:索引 indices 是否排序
3.CSC - csc_matrix
Compressed Sparse Column Matrix 壓縮稀疏列矩陣
- csc_matrix是按列對矩陣進行壓縮的
- 通過 indices, indptr,data 來確定矩陣,可以對比CSR
- data 表示矩陣中的非零數據
- 對于第 i 列而言,該行中非零元素的行索引為indices[indptr[i]:indptr[i+1]]
- 可以將 indptr 理解成利用其自身索引 i 來指向第 i 列元素的列索引
- 根據[indptr[i]:indptr[i+1]],我就得到了該行中的非零元素個數,如
- 若 index[i] = 1 且 index[i+1] = 1 ,則第 i 列的沒有非零元素
- 若 index[j] = 4 且 index[j+1] = 6 ,則第 j列的非零元素的行索引為 indices[4:6]
- 得到了列索引、行索引,相應的數據存放在: data[indptr[i]:indptr[i+1]]
- 對于矩陣第 0 列,我們需要先得到其非零元素行索引
- 由 indptr[0] = 0 和 indptr[1] = 1 可知,第 0列行有1個非零元素。
- 它們的行索引為 indices[0:1] = [0] ,且存放的數據為 data[0] = 8
- 因此矩陣第 0 行的非零元素 csc[0][0] = 8
- 對于矩陣第 3 列,同樣我們需要先計算其非零元素行索引
- 由 indptr[3] = 4 和 indptr[4] = 6 可知,第 4 行有2個非零元素。
- 它們的行索引為 indices[4:6] = [4, 6] ,且存放的數據為 data[4] = 1 ,data[5] = 9
- 因此矩陣第 i 行的非零元素 csr[4][3] = 1 , csr[6][3] = 9
應用場景
參考CSR
優缺點
對比參考CSR
實例化
- csc_matrix(D):D代表密集矩陣;
- csc_matrix(S):S代表其他類型稀疏矩陣
- csc_matrix((M, N), [dtype]):構建一個shape為M*N的空矩陣,默認數據類型是d,
- csc_matrix((data, (row_ind, col_ind)), [shape=(M, N)]))
- 三者關系:a[row_ind[k], col_ind[k]] = data[k]
- csc_matrix((data, indices, indptr), [shape=(M, N)])
- 第i列的列索引存儲在其中indices[indptr[i]:indptr[i+1]]
- 其對應值存儲在中data[indptr[i]:indptr[i+1]]
特殊屬性
- data :稀疏矩陣存儲的值,一維數組
- indices :存儲矩陣有有非零值的行索引
- indptr :類似指向列索引的指針數組
- has_sorted_indices :索引是否排序
4. BSR - bsr_matrix
Block Sparse Row Matrix 分塊壓縮稀疏行格式
- 基于行的塊壓縮,與csr類似,都是通過data,indices,indptr來確定矩陣
- 與csr相比,只是data中的元數據由0維的數變為了一個矩陣(塊),其余完全相同
- 塊大小 blocksize
- 塊大小 (R, C) 必須均勻劃分矩陣 (M, N) 的形狀。
- R和C必須滿足關系:M % R = 0 和 N % C = 0
- 適用場景及優點參考csr
實例化
- bsr_matrix(D):D代表密集矩陣;
- bsr_matrix(S):S代表其他類型稀疏矩陣
- bsr_matrix((M, N), [blocksize =(R,C), [dtype]):構建一個shape為M*N的空矩陣,默認數據類型是d,
- (data, ij), [blocksize=(R,C), shape=(M, N)]
- 兩者關系:a[ij[0,k], ij[1,k]] = data[k]]
- bsr_matrix((data, indices, indptr), [shape=(M, N)])
- 第i行的塊索引存儲在其中indices[indptr[i]:indptr[i+1]]
- 其相應塊值存儲在中data[indptr[i]:indptr[i+1]]
特殊屬性
- data :稀疏矩陣存儲的值,一維數組
- indices :存儲矩陣有有非零值的列索引
- indptr :類似指向列索引的指針數組
- blocksize :矩陣的塊大小
- has_sorted_indices:索引 indices 是否排序
代碼示例
# 生成數據 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]).repeat(4).reshape(6,2,2)# 創建矩陣 bsr = bsr_matrix((data, indices, indptr), shape=(6,6)).todense()# 轉為array bsr.todense() matrix([[1, 1, 0, 0, 2, 2],[1, 1, 0, 0, 2, 2],[0, 0, 0, 0, 3, 3],[0, 0, 0, 0, 3, 3],[4, 4, 5, 5, 6, 6],[4, 4, 5, 5, 6, 6]])優缺點
①優點
- 與csr很類似
- 更適合于適用于具有密集子矩陣的稀疏矩陣
- 在某些情況下比csr和csc計算更高效。
5. DOK- dok_matrix
Dictionary of Keys Matrix 按鍵字典矩陣
- 采用字典來記錄矩陣中不為0的元素
- 字典的 key 存的是記錄元素的位置信息的元組, value 是記錄元素的具體值
適用場景
- 逐漸添加矩陣的元素
實例化方法
- dok_matrix(D):D代表密集矩陣;
- dok_matrix(S):S代表其他類型稀疏矩陣
- dok_matrix((M, N), [dtype]):構建一個shape為M*N的空矩陣,默認數據類型是d
優缺點
①優點
- 對于遞增的構建稀疏矩陣很高效,比如定義該矩陣后,想進行每行每列更新值,可用該矩陣。
- 可以高效訪問單個元素,只需要O(1)
②缺點
- 不允許重復索引(coo中適用),但可以很高效的轉換成coo后進行重復索引
代碼示例
dok = sparse.dok_matrix((5, 5), dtype=np.float32) for i in range(5):for j in range(5):dok[i,j] = i+j # 更新元素# zero elements are accessible dok[(0, 0)] # = 0dok.keys() # {(0, 0), ..., (4, 4)}dok.toarray() ''' [[0. 1. 2. 3. 4.][1. 2. 3. 4. 5.][2. 3. 4. 5. 6.][3. 4. 5. 6. 7.][4. 5. 6. 7. 8.]]'''6. LIL - lil_matrix
Linked List Matrix 鏈表矩陣
- 使用兩個列表存儲非0元素data
- rows保存非零元素所在的列
- 可以使用列表賦值來添加元素,如 lil[(0, 0)] = 8
- lil[(0, -1)] = 4 :第0行的最后一列元素為4
- lil[(4, 2)] = 5 :第4行第2列的元素為5
適用場景
- 適用的場景是逐漸添加矩陣的元素(且能快速獲取行相關的數據)
- 需要注意的是,該方法插入一個元素最壞情況下可能導致線性時間的代價,所以要確保對每個元素的索引進行預排序
優缺點
①優點
- 適合遞增的構建成矩陣
- 轉換成其它存儲方式很高效
- 支持靈活的切片
②缺點
- 當矩陣很大時,考慮用coo
- 算術操作,列切片,矩陣向量內積操作慢
實例化方法
- lil_matrix(D):D代表密集矩陣;
- lil_matrix(S):S代表其他類型稀疏矩陣
- lil_matrix((M, N), [dtype]):構建一個shape為M*N的空矩陣,默認數據類型是d
特殊屬性
- data:存儲矩陣中的非零數據
- rows:存儲每個非零元素所在的列(行信息為列表中索引所表示)
代碼示例
# 創建矩陣 lil = sparse.lil_matrix((6, 5), dtype=int)# 設置數值 # set individual point lil[(0, -1)] = -1 # set two points lil[3, (0, 4)] = [-2] * 2 # set main diagonal lil.setdiag(8, k=0)# set entire column lil[:, 2] = np.arange(lil.shape[0]).reshape(-1, 1) + 1# 轉為array lil.toarray() ''' array([[ 8, 0, 1, 0, -1],[ 0, 8, 2, 0, 0],[ 0, 0, 3, 0, 0],[-2, 0, 4, 8, -2],[ 0, 0, 5, 0, 8],[ 0, 0, 6, 0, 0]]) '''# 查看數據 lil.data ''' array([list([0, 2, 4]), list([1, 2]), list([2]), list([0, 2, 3, 4]),list([2, 4]), list([2])], dtype=object) ''' lil.rows ''' array([[list([8, 1, -1])],[list([8, 2])],[list([3])],[list([-2, 4, 8, -2])],[list([5, 8])],[list([6])]], dtype=object) '''7. DIA - dia_matrix
Diagonal Matrix 對角存儲格式
- 最適合對角矩陣的存儲方式
- dia_matrix通過兩個數組確定: data 和 offsets
- data :對角線元素的值
- offsets :第 i 個 offsets 是當前第 i 個對角線和主對角線的距離
- data[k:] 存儲了 offsets[k] 對應的對角線的全部元素
- 當 offsets[0] = 0 時,表示該對角線即是主對角線,相應的值為 [1, 2, 3, 4, 5]
- 當 offsets[2] = 2 時,表示該對角線為主對角線向上偏移2個單位,相應的值為 [11, 12, 13, 14, 15]
- 但該對角線上元素僅有三個 ,于是采用先出現的元素無效的原則
- 即前兩個元素對構造矩陣無效,故該對角線上的元素為 [13, 14, 15]
實例化方法
- dia_matrix(D):D代表密集矩陣;
- dia_matrix(S):S代表其他類型稀疏矩陣
- dia_matrix((M, N), [dtype]):構建一個shape為M*N的空矩陣,默認數據類型是d
- dia_matrix((data, offsets)), [shape=(M, N)])):data[k,:] 存儲著對角偏移量為 offset[k] 的對角值
特殊屬性
- data:存儲DIA對角值的數組
- offsets:存儲DIA對角偏移量的數組
代碼示例
# 生成數據 data = np.array([[1, 2, 3, 4], [5, 6, 0, 0], [0, 7, 8, 9]]) offsets = np.array([0, -2, 1])# 創建矩陣 dia = sparse.dia_matrix((data, offsets), shape=(4, 4))# 查看數據 dia.data ''' array([[[1 2 3 4][5 6 0 0][0 7 8 9]]) '''# 轉為array dia.toarray() ''' array([[1 7 0 0][0 2 8 0][5 0 3 9][0 6 0 4]]) '''矩陣格式對比
稀疏矩陣存取
存儲 - save_npz
scipy.sparse.save_npz('sparse_matrix.npz', sparse_matrix) sparse_matrix = scipy.sparse.load_npz('sparse_matrix.npz')讀取 - load_npz
# 從npz文件中讀取 test_x = sparse.load_npz('./data/npz/test_x.npz')存儲大小比較
a = np.arange(100000).reshape(1000,100) a[10: 300] = 0 b = sparse.csr_matrix(a)# 稀疏矩陣壓縮存儲到npz文件 sparse.save_npz('b_compressed.npz', b, True) # 文件大小:100KB# 稀疏矩陣不壓縮存儲到npz文件 sparse.save_npz('b_uncompressed.npz', b, False) # 文件大小:560KB# 存儲到普通的npy文件 np.save('a.npy', a) # 文件大小:391KB# 存儲到壓縮的npz文件 np.savez_compressed('a_compressed.npz', a=a) # 文件大小:97KB? 1對于存儲到npz文件中的CSR格式的稀疏矩陣,內容為:
data.npy format.npy indices.npy indptr.npy shape.npy參考
Sparse matrices (scipy.sparse)Sparse Matrices
python稀疏矩陣的存儲與表示
python scipy 稀疏矩陣詳解
SciPy教程 - 稀疏矩陣庫scipy.sparse
總結
以上是生活随笔為你收集整理的稀疏矩阵三元组 严蔚敏_Sparse稀疏矩阵主要存储格式总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAVA窗口sin值_大厂经典笔试题—L
- 下一篇: windows nginx c++读取请