python 的csr_python的高级数组之稀疏矩阵
稀疏矩陣的定義:
具有少量非零項(xiàng)的矩陣(在矩陣中,若數(shù)值0的元素?cái)?shù)目遠(yuǎn)多于非0元素的數(shù)目,并且非0元素分布沒(méi)有規(guī)律時(shí),)則稱該矩陣為稀疏矩陣;相反,為稠密矩陣。非零元素的總數(shù)比上矩陣所有元素的總數(shù)為矩陣的稠密度。
稀疏矩陣的兩個(gè)動(dòng)機(jī):稀疏矩陣通常具有很大的維度,有時(shí)甚大到整個(gè)矩陣(零元素)與可用內(nèi)存不想適應(yīng);另一個(gè)動(dòng)機(jī)是避免零矩陣元素的運(yùn)算具有更好的性能。
稀疏矩陣的格式
存儲(chǔ)矩陣的一般方法是采用二維數(shù)組,其優(yōu)點(diǎn)是可以隨機(jī)地訪問(wèn)每一個(gè)元素,因而能夠容易實(shí)現(xiàn)矩陣的各種運(yùn)算。對(duì)于稀疏矩陣,采用二維數(shù)組的存儲(chǔ)方法既浪費(fèi)大量的存儲(chǔ)單元來(lái)存放零元素,又要在運(yùn)算中浪費(fèi)大量的時(shí)間來(lái)進(jìn)行零元素的無(wú)效運(yùn)算。因此必須考慮對(duì)稀疏矩陣進(jìn)行壓縮存儲(chǔ)(只存儲(chǔ)非零元素)。
Scipy.sparse模塊提供了許多來(lái)自于稀疏矩陣的不同存儲(chǔ)格式。這里僅描述最為重要的格式CSR、CSC和LIL。CSR、CSC是用于矩陣-矩陣和矩陣-向量運(yùn)算的有效格式,LIL格式用于生成和更改稀疏矩陣。Python不能自動(dòng)創(chuàng)建稀疏矩陣,所以要用scipy中特殊的命令來(lái)得到稀疏矩陣。
(1)?壓縮稀疏行(CSR,Compressed Sparse Row):或csr_matrix??按行對(duì)矩陣進(jìn)行壓縮的。
CSR使用了三個(gè)數(shù)組,分別為數(shù)值、行偏移(表示某一行的第一個(gè)元素在數(shù)值里面的起始偏移位置,在行偏移的最后補(bǔ)上矩陣總的元素個(gè)數(shù))、列號(hào)。CSR是一種編碼的方式
一維數(shù)組data(數(shù)值):有序地存儲(chǔ)了所有的非零值,它具有與非零元素同樣多數(shù)量的元素,通常由變量nnz表示。
一維數(shù)組indptr(行偏移量):包含了證書(shū)使得indptr[i]是data中元素的索引,它是行i中的第一個(gè)非零元素。如果整個(gè)行i為零,則indptr[i]==indptr[i+1]
如初始矩陣有m行,則len(indptr)==m+1
一維數(shù)組Indices(列號(hào):):其使用如下方式包含列索引信息:indices[indptr[i]:indptr[i+1]]是一個(gè)具有行i中非零元素的列索引的整數(shù)數(shù)組。Len(indice)==len(data)==nnz
備注:列索引表示數(shù)值所在的列號(hào),從0開(kāi)始。
數(shù)組data:包含矩陣中的非零元素,以行優(yōu)先的形式保存。
行偏移:CSR中行索引被壓縮,沒(méi)有行索引,這里用行偏移表示行索引。
實(shí)例:
如上圖所示:data=(1,7,2,8,5,3,9,6,4)
Indices=(0,1,1,2,0,2,3,1,3) ???#列索引
Indptr=(0,2,4,7,9) ?#行偏移(表示某一行的第一個(gè)元素在數(shù)值里面的起始偏移位置,在行偏移的最后補(bǔ)上矩陣總的元素個(gè)數(shù))
在Python中使用:
import numpy as np
from scipy.sparse import csr_matrix
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])
A=csr_matrix((data, indices, indptr), shape=(3, 3)).toarray()#生成CSR格式的矩陣
print(A) ???#運(yùn)行結(jié)果:
[[1 0 2]
[0 0 3]
[4 5 6]]
解析:第i行的列索引存儲(chǔ)在indices[indptr[i]:indptr[i+1]]中,對(duì)應(yīng)的值為data[indptr[i]:indptr[i+1]]。即例如第0行的列索引為indices[0:2]=[0,2](第i行中非零元素的列索引組成的整數(shù)數(shù)組),值為data[0:2]=[1,2];第1行的列索引為indices[2:3]=[2],值為data[2:3]=[3]…
(2)?稀疏列矩陣CSC(Compressed Sparse Column),用于CSC格式的類(lèi)型為:csc_matrix按列對(duì)矩陣進(jìn)行壓縮的。
與CSR格式相比唯一的不同點(diǎn)是indptr和indices數(shù)組的定義,該定義與列有關(guān)。
CSC格式的實(shí)例:
import numpy as np
import scipy.sparse as sp
A=np.array([[1,0,2,0],[0,0,0,0],[3,0,0,0],[1,0,0,4]])
AS=sp.csc_matrix(A)
Print(AS)
print(AS.data)
print(AS.indptr)
print(AS.indices)
print(AS.nnz) ???#運(yùn)行結(jié)果:
[1 3 1 2 4]
[0 3 3 4 5] ????#注意此處,同一矩陣CSR格式的indptr為[0 2 2 3 5]
[0 2 3 0 3]
5
(3)?基于行的鏈表格式:LIL(Row-Based Linked List Format)
1. 鏈表稀疏格式在列表數(shù)據(jù)中以行方式存儲(chǔ)非零元素,
列表data: data[k]是行k中的非零元素的列表。如果該行中的所有元素都為0,則它包含一個(gè)空列表。
列表rows:?是在位置k包含了在行k中的非零元素列索引列表。
LIL格式的同一示例:
import numpy as np
import scipy.sparse as sp
A=np.array([[1,0,2,0],[0,0,0,0],[3,0,0,0],[1,0,0,4]])
AS=sp.lil_matrix(A)
print(AS.data)
print(AS.rows)
print(AS.nnz) ?#運(yùn)行結(jié)果:
[list([1, 2]) list([]) list([3]) list([1, 4])]
[list([0, 2]) list([]) list([0]) list([0, 3])]
5
2. 用LIL格式更改和切割矩陣:
LIL格式最適合切片的方法,即以LIL格式提取子矩陣,并通過(guò)插入非零元素來(lái)改變稀疏模式。
例如:提取
import numpy as np
import scipy.sparse as sp
A=np.array([[1,0,2,0],[0,0,0,0],[3,0,0,0],[1,0,0,4]])
AS=sp.lil_matrix(A)
print(AS)
BS=AS[0:2,0:3] ?????#切片提取0,1行,0,1,2列組成的子矩陣
print(BS)
print(BS.data)
print(BS.rows)
#運(yùn)行結(jié)果:
(0, 0) ???????1
(0, 2) ???????2
[list([1, 2]) list([])]
[list([0, 2]) list([])]
更改:插入新的非零元素會(huì)自動(dòng)更新屬性
AS[0,1]=17
print(AS.data)
print(AS.rows)
print(AS.nnz)
#結(jié)果:[list([1, 17, 2]) list([]) list([3]) list([1, 4])]
[list([0, 1, 2]) list([]) list([0]) list([0, 3])]
6
生成稀疏矩陣:
Numpy包的命令eye、identity、diag和rand都有其對(duì)應(yīng)的稀疏矩陣,這些命令需要額外的參數(shù)來(lái)指定所得矩陣的稀疏矩陣格式。
import numpy as np
import scipy.sparse as sp
print(sp.eye(20,20,format = 'lil'))
print(sp.spdiags(np.ones((20,)),0,20,20,format = 'csr'))
print(sp.identity(20,format =?'csc'))
print(sp.rand(20,200,density=0.1,format='csr')) ???#sp.rand命令需要額外的參數(shù)來(lái)描述生成隨機(jī)矩陣的密度。
稀疏矩陣方法
將稀疏矩陣類(lèi)型轉(zhuǎn)換為另一種類(lèi)型和數(shù)據(jù)或數(shù)組的方法:
AS.toarray ?#轉(zhuǎn)換稀疏矩陣類(lèi)型為數(shù)組
AS.tocsr
AS.tocsc
AS.tolil
#通過(guò)issparse、isspmatrix_lil、isspmatrix_csc、isspmatrix_csr等方法檢查稀疏矩陣的類(lèi)型。
import numpy as np
import scipy.sparse as sp
A=np.array([[1,0,2,0],[0,0,0,0],[3,0,0,0],[1,0,0,4]])
def sparse_sin(A):
if not (sp.isspmatrix_csr(A) or sp.isspmatrix_csc(A)):
A=A.tocsr()
A.data=sin(A.data)
return(A)
B=sparse_sin(A)
print(B)
#稀疏矩陣方法的dot,用于矩陣-矩陣或者矩陣-向量乘法運(yùn)算,返回csr_matrix或Numpy array
例如:import numpy as np
import scipy.sparse as sp
A=np.array([[1,0,2,0],[0,0,0,0],[3,0,0,0],[1,0,0,4]])
AS=sp.csr_matrix(A)
b=np.array([1,2,3,4])
c=AS.dot(b) ????#結(jié)果為:[ 7 ?0 3 ?17]
print(c)
c=AS.dot(AS) ???????#結(jié)果仍為稀疏矩陣
print(c)
d=np.dot(AS,b)
print(d) ????#不能返回期望的結(jié)果
總結(jié)
以上是生活随笔為你收集整理的python 的csr_python的高级数组之稀疏矩阵的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python lock_python多线
- 下一篇: python gitlab_Python