主頁 > 知識(shí)庫 > python scipy 稀疏矩陣的使用說明

python scipy 稀疏矩陣的使用說明

熱門標(biāo)簽:客戶服務(wù) 呼叫中心市場需求 百度AI接口 硅谷的囚徒呼叫中心 電話運(yùn)營中心 語音系統(tǒng) Win7旗艦版 企業(yè)做大做強(qiáng)

稀疏矩陣格式 coo_matrix

coo_matrix

是最簡單的稀疏矩陣存儲(chǔ)方式,采用三元組(row, col, data)(或稱為ijv format)的形式來存儲(chǔ)矩陣中非零元素的信息。

在實(shí)際使用中,一般coo_matrix用來創(chuàng)建矩陣,因?yàn)閏oo_matrix無法對矩陣的元素進(jìn)行增刪改操作;創(chuàng)建成功之后可以轉(zhuǎn)化成其他格式的稀疏矩陣(如csr_matrix、csc_matrix)進(jìn)行轉(zhuǎn)置、矩陣乘法等操作。

coo_matrix可以通過四種方式實(shí)例化,除了可以通過coo_matrix(D), D代表密集矩陣;coo_matrix(S), S代表其他類型稀疏矩陣或者coo_matrix((M, N), [dtype])構(gòu)建一個(gè)shape為M*N的空矩陣,默認(rèn)數(shù)據(jù)類型是d,還可以通過(row, col, data)三元組初始化:

>>> import numpy as np
>>> from scipy.sparse import coo_matrix
>>> _row  = np.array([0, 3, 1, 0])
>>> _col  = np.array([0, 3, 1, 2])
>>> _data = np.array([4, 5, 7, 9])
>>> coo = coo_matrix((_data, (_row, _col)), shape=(4, 4), dtype=np.int)
>>> coo.todense()  # 通過toarray方法轉(zhuǎn)化成密集矩陣(numpy.matrix)
>>> coo.toarray()  # 通過toarray方法轉(zhuǎn)化成密集矩陣(numpy.ndarray)
array([[4, 0, 9, 0],
       [0, 7, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 5]])

上面通過triplet format的形式構(gòu)建了一個(gè)coo_matrix對象,我們可以看到坐標(biāo)點(diǎn)(0,0)對應(yīng)值為4,坐標(biāo)點(diǎn)(1,1)對應(yīng)值為7等等,這就是coo_matrix。coo_matrix對象有很多方法,大多數(shù)是elementwise的操作函數(shù);coo_matrix對象有以下屬性:

dtype dtype

矩陣中元素的數(shù)據(jù)類型

shape 2-tuple

獲取矩陣的shape

ndim int

獲取矩陣的維度,當(dāng)然值是2咯

nnz

存儲(chǔ)值的個(gè)數(shù),包括顯示聲明的零元素(注意)

data

稀疏矩陣存儲(chǔ)的值,是一個(gè)一維數(shù)組,即上面例子中的_data

row

與data同等長度的一維數(shù)組,表征data中每個(gè)元素的行號(hào)

col

與data同等長度的一維數(shù)組,表征data中每個(gè)元素的列號(hào)

在實(shí)際應(yīng)用中,coo_matrix矩陣文件通常存成以下形式,表示稀疏矩陣是coo_matrix(coordinate),由13885行1列組成,共有949個(gè)元素值為非零,數(shù)據(jù)類型為整形。

​ 下面給出coo_matrix矩陣文件讀寫示例代碼,mmread()用于讀取稀疏矩陣,mmwrite()用于寫入稀疏矩陣,mminfo()用于查看稀疏矩陣文件元信息。(這三個(gè)函數(shù)的操作不僅僅限于coo_matrix)

from scipy.io import mmread, mmwrite, mminfo
HERE = dirname(__file__)
coo_mtx_path = join(HERE, 'data/matrix.mtx')
coo_mtx = mmread(coo_mtx_path)
print(mminfo(coo_mtx_path))
# (13885, 1, 949, 'coordinate', 'integer', 'general')
# (rows, cols, entries, format, field, symmetry)
mmwrite(join(HERE, 'data/saved_mtx.mtx'), coo_mtx)

coo_matrix的優(yōu)點(diǎn):

有利于稀疏格式之間的快速轉(zhuǎn)換(tobsr()、tocsr()、to_csc()、to_dia()、to_dok()、to_lil())

允許又重復(fù)項(xiàng)(格式轉(zhuǎn)換的時(shí)候自動(dòng)相加)

能與CSR / CSC格式的快速轉(zhuǎn)換

coo_matrix的缺點(diǎn):

不能直接進(jìn)行算術(shù)運(yùn)算

csr_matrix ​

csr_matrix,全稱Compressed Sparse Row matrix,即按行壓縮的稀疏矩陣存儲(chǔ)方式,由三個(gè)一維數(shù)組indptr, indices, data組成。

這種格式要求矩陣元按行順序存儲(chǔ),每一行中的元素可以亂序存儲(chǔ)。

那么對于每一行就只需要用一個(gè)指針表示該行元素的起始位置即可。

indptr存儲(chǔ)每一行數(shù)據(jù)元素的起始位置,indices這是存儲(chǔ)每行中數(shù)據(jù)的列號(hào),與data中的元素一一對應(yīng)。

csr_matrix可用于各種算術(shù)運(yùn)算:它支持加法,減法,乘法,除法和矩陣冪等操作。

其有五種實(shí)例化方法,其中前四種初始化方法類似coo_matrix,即通過密集矩陣構(gòu)建、通過其他類型稀疏矩陣轉(zhuǎn)化、構(gòu)建一定shape的空矩陣、通過(row, col, data)構(gòu)建矩陣。

其第五種初始化方式這是直接體現(xiàn)csr_matrix的存儲(chǔ)特征:csr_matrix((data, indices, indptr), [shape=(M, N)]),意思是,矩陣中第i行非零元素的列號(hào)為indices[indptr[i]:indptr[i+1]],相應(yīng)的值為data[indptr[i]:indptr[i+1]]

舉個(gè)例子:

>>> 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])
>>> csr = csr_matrix((data, indices, indptr), shape=(3, 3)).toarray()
array([[1, 0, 2],
       [0, 0, 3],
       [4, 5, 6]])

csr_matrix同樣有很多方法,其中tobytes(),tolist(), tofile(),tostring()值得注意,其他具體參考官方文檔,csr_matrix對象屬性前五個(gè)同coo_matrix,另外還有屬性如下:

indices

與屬性data一一對應(yīng),元素值代表在某一行的列號(hào)

indptr

csr_matrix各行的起始值,length(csr_object.indptr) == csr_object.shape[0] + 1

has_sorted_indices

判斷每一行的indices是否是有序的,返回bool值

csr_matrix的優(yōu)點(diǎn):

高效的算術(shù)運(yùn)算CSR + CSR,CSR * CSR等高效的行切片快速矩陣運(yùn)算

csr_matrix的缺點(diǎn):

列切片操作比較慢(考慮csc_matrix)稀疏結(jié)構(gòu)的轉(zhuǎn)換比較慢(考慮lil_matrix或doc_matrix)

csc_matrix

​ csc_matrix和csr_matrix正好相反,即按列壓縮的稀疏矩陣存儲(chǔ)方式,同樣由三個(gè)一維數(shù)組indptr, indices, data組成,如下圖所示:

其實(shí)例化方式、屬性、方法、優(yōu)缺點(diǎn)和csr_matrix基本一致,這里不再贅述,它們之間唯一的區(qū)別就是按行或按列壓縮進(jìn)行存儲(chǔ)。

而這一區(qū)別決定了csr_matrix擅長行操作;csc_matrix擅長列操作,進(jìn)行運(yùn)算時(shí)需要進(jìn)行合理存儲(chǔ)結(jié)構(gòu)的選擇。

lil_matrix

​ lil_matrix,即List of Lists format,又稱為Row-based linked list sparse matrix。它使用兩個(gè)嵌套列表存儲(chǔ)稀疏矩陣:data保存每行中的非零元素的值,rows保存每行非零元素所在的列號(hào)(列號(hào)是順序排序的)。

這種格式很適合逐個(gè)添加元素,并且能快速獲取行相關(guān)的數(shù)據(jù)。

其初始化方式同coo_matrix初始化的前三種方式:通過密集矩陣構(gòu)建、通過其他矩陣轉(zhuǎn)化以及構(gòu)建一個(gè)一定shape的空矩陣。

lil_matrix可用于算術(shù)運(yùn)算:支持加法,減法,乘法,除法和矩陣冪。其屬性前五個(gè)同coo_matrix,另外還有rows屬性,是一個(gè)嵌套List,表示矩陣每行中非零元素的列號(hào)。

LIL matrix本身的設(shè)計(jì)是用來方便快捷構(gòu)建稀疏矩陣實(shí)例,而算術(shù)運(yùn)算、矩陣運(yùn)算則轉(zhuǎn)化成CSC、CSR格式再進(jìn)行,構(gòu)建大型的稀疏矩陣還是推薦使用COO格式。

LIL format優(yōu)點(diǎn)

支持靈活的切片操作行切片操作效率高,列切片效率低

稀疏矩陣格式之間的轉(zhuǎn)化很高效(tobsr()、tocsr()、to_csc()、to_dia()、to_dok()、to_lil())

LIL format缺點(diǎn)

加法操作效率低 (consider CSR or CSC)

列切片效率低(consider CSC)

矩陣乘法效率低 (consider CSR or CSC)

dok_matrix ​

dok_matrix,即Dictionary Of Keys based sparse matrix,是一種類似于coo matrix但又基于字典的稀疏矩陣存儲(chǔ)方式,key由非零元素的的坐標(biāo)值tuple(row, column)組成,value則代表數(shù)據(jù)值。

dok matrix非常適合于增量構(gòu)建稀疏矩陣,并一旦構(gòu)建,就可以快速地轉(zhuǎn)換為coo_matrix。

其屬性和coo_matrix前四項(xiàng)同;其初始化方式同coo_matrix初始化的前三種:通過密集矩陣構(gòu)建、通過其他矩陣轉(zhuǎn)化以及構(gòu)建一個(gè)一定shape的空矩陣。

對于dok matrix,可用于算術(shù)運(yùn)算:它支持加法,減法,乘法,除法和矩陣冪;允許對單個(gè)元素進(jìn)行快速訪問( O(1) ); 不允許重復(fù)。

>>> import numpy as np
>>> from scipy.sparse import dok_matrix
>>> np.random.seed(10)
>>> matrix = random(3, 3, format='dok', density=0.4)
>>> matrix[1, 1] = 33
>>> matrix[2, 1] = 10
>>> matrix.toarray()
array([[ 0.        ,  0.        ,  0.        ],
       [ 0.        , 33.        ,  0.        ],
       [ 0.19806286, 10.        ,  0.22479665]])
>>> dict(matrix)
{(2, 0): 0.19806286475962398, (2, 1): 10.0, (2, 2): 0.22479664553084766, (1, 1): 33.0}
>>> isinstance(matrix, dict)
True

在上面代碼最后可以看到,實(shí)際上dok_matrix實(shí)例也是dict實(shí)例,在實(shí)現(xiàn)上繼承了dict類。

dia_matrix

​ dia_matrix,全稱Sparse matrix with DIAgonal storage,是一種對角線的存儲(chǔ)方式。

如下圖中,將稀疏矩陣使用offsets和data兩個(gè)矩陣來表示。offsets表示data中每一行數(shù)據(jù)在原始稀疏矩陣中的對角線位置k(k>0, 對角線往右上角移動(dòng);k0, 對角線往左下方移動(dòng);k=0,主對角線)。

該格式的稀疏矩陣可用于算術(shù)運(yùn)算:它們支持加法,減法,乘法,除法和矩陣冪。

​dia_matrix五個(gè)屬性同coo matrix, 另外還有屬性offsets;dia_matrix有四種初始化方式,其中前三種初始化方式同coo_matrix前三種初始化方式,即:通過密集矩陣構(gòu)建、通過其他矩陣轉(zhuǎn)化以及構(gòu)建一個(gè)一定shape的空矩陣。

第四種初始化方式如下:

dia_matrix((data, offsets), shape=(M, N)) ,

​ 其中,data[k,:]存儲(chǔ)著稀疏矩陣offsets[k]對角線上的值

>>> data = np.arange(15).reshape(3, -1) + 1
>>> offsets = np.array([0, -3, 2])
>>> dia = sparse.dia_matrix((data, offsets), shape=(7, 5))
>>> dia.toarray()
array([[ 1,  0, 13,  0,  0],
       [ 0,  2,  0, 14,  0],
       [ 0,  0,  3,  0, 15],
       [ 6,  0,  0,  4,  0],
       [ 0,  7,  0,  0,  5],
       [ 0,  0,  8,  0,  0],
       [ 0,  0,  0,  9,  0]])

不是很常用,了解即可

bsr_matrix

​ bsr_matrix,全稱Block Sparse Row matrix,這種壓縮方式極其類似CSR格式,但使用分塊的思想對稀疏矩陣進(jìn)行按行壓縮。所以,BSR適用于具有dense子矩陣的稀疏矩陣。該種矩陣有五種初始化方式,分別如下:

bsr_matrix(D, [blocksize=(R,C)])

D是一個(gè)M*N的二維dense矩陣;blocksize需要滿足條件:M % R = 0和N % C = 0,若不給定該參數(shù),內(nèi)部將會(huì)應(yīng)用啟發(fā)式的算法自動(dòng)決定一個(gè)合適的blocksize.

bsr_matrix(S, [blocksize=(R,C)])

S是指其他類型的稀疏矩陣

bsr_matrix((M, N), [blocksize=(R,C), dtype])

構(gòu)建一個(gè)shape為M*N的空矩陣

bsr_matrix((data, ij), [blocksize=(R,C), shape=(M, N)])

data 和ij 滿足條件: a[ij[0, k], ij[1, k]] = data[k]

bsr_matrix((data, indices, indptr), [shape=(M, N)])

data.shape一般是k*R*C,其中R、C分別代表block的行和列長,k代表有幾個(gè)小block矩陣;第i行的塊列索引存儲(chǔ)在indices[indptr[i]:indptr[i+1]],其值是data[ indptr[i]: indptr[i+1] ]。

bsr_matrix可用于算術(shù)運(yùn)算:支持加法,減法,乘法,除法和矩陣冪。如下面的例子,對于許多稀疏算術(shù)運(yùn)算,BSR比CSR和CSC更有效:

>>> from scipy.sparse import bsr_matrix
>>> import numpy
>>> 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_matrix((data,indices,indptr), shape=(6, 6)).toarray()
array([[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]])

可以通過熱圖觀察矩陣有沒有明顯分塊模式再?zèng)Q定使不使用該方式

bsr matrix對象擁有9個(gè)屬性,前四個(gè)屬性與coo matrix相同,另外還有以下屬性(注意csr matrix和bsr matrix之間的區(qū)別與聯(lián)系):

data

即稀疏矩陣的數(shù)組,data.shape一般是k*R*C

indices

與屬性data中的k個(gè)二維矩陣一一對應(yīng),元素值代表在某一行的列號(hào)

indptr

bsr各行起始起始值

blocksize

即tuple(R,C)

has_sorted_indices

判斷每一行的indices是否是有序的,返回bool值

實(shí)用函數(shù)

構(gòu)造特殊稀疏矩陣

scipy.sparse模塊還包含一些便捷函數(shù),用于快速構(gòu)建單位矩陣、對角矩陣等,下面做一個(gè)簡單的匯總:

方法 用途
identity(n[, dtype, format]) 生成稀疏單位矩陣
kron(A, B[, format]) sparse matrices A 和 B的克羅內(nèi)克積
kronsum(A, B[, format]) sparse matrices A 和 B的克羅內(nèi)克和
diags(diagonals[, offsets, shape, format, dtype]) 構(gòu)建稀疏對角陣
spdiags(data, diags, m, n[, format]) 構(gòu)建稀疏對角陣,同上,但不可指定shape
block_diag(mats[, format, dtype]) mats為iterable, 包含多個(gè)矩陣,根據(jù)mats構(gòu)建塊對角稀疏矩陣。
tril(A[, k, format]) 以稀疏格式返回矩陣的下三角部分
triu(A[, k, format]) 以稀疏格式返回矩陣的上三角部分
bmat(blocks[, format, dtype]) 從稀疏子塊構(gòu)建稀疏矩陣
hstack(blocks[, format, dtype]) 水平堆疊稀疏矩陣(column wise)
vstack(blocks[, format, dtype]) 垂直堆疊稀疏矩陣 (row wise)
rand(m, n[, density, format, dtype, …]) 使用均勻分布的值生成給定形狀和密度的稀疏矩陣
random(m, n[, density, format, dtype, …]) 使用隨機(jī)分布的值生成給定形狀和密度的稀疏矩陣
eye(m[, n, k, dtype, format]) 生成稀疏單位對角陣(默認(rèn)DIAgonal format)

​ scipy.sparse.bmat舉例:

In [1]: A = np.arange(8).reshape(2, 4)
In [2]: T = np.tri(5, 4)
In [3]: L = [[8] * 4] * 2
In [4]: I = sparse.identity(4)
In [5]: Z = sparse.coo_matrix((2, 3))
In [6]: sp.bmat([[   A,    Z,    L],
    ...:          [None, None,    I],
    ...:          [   T, None, None]], dtype=int)
Out[7]:
11x11 sparse matrix of type 'class 'numpy.int64'>'
        with 33 stored elements in COOrdinate format>
In [8]: _.toarray()  # ipython previous output
Out[9]:
array([[0, 1, 2, 3, 0, 0, 0, 8, 8, 8, 8],
       [4, 5, 6, 7, 0, 0, 0, 8, 8, 8, 8],
       [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]])

稀疏矩陣類型判斷

scipy.sparse模塊還包含一些判斷稀疏矩陣類型的函數(shù),這里需要注意的是,issparse() 和 isspmatrix() 是相同的函數(shù),也許是由于歷史原因保留下來了兩個(gè)。

isspars(x)
isspmatrix(x)
isspmatrix_csc(x)
isspmatrix_csr(x)
isspmatrix_bsr(x)
isspmatrix_lil(x)
isspmatrix_dok(x)
isspmatrix_coo(x)
isspmatrix_dia(x)

稀疏矩陣存取

load_npz(file) 從.npz文件中讀取稀疏矩陣

save_npz(file, matrix[,compressed]) 將稀疏矩陣寫入.npz文件中

其他

find(A) 返回稀疏矩陣中非零元素的索引以及值

經(jīng)驗(yàn)總結(jié)

要有效地構(gòu)造矩陣,請使用dok_matrix或lil_matrix

lil_matrix類支持基本切片和花式索引,其語法與NumPy Array類似;lil_matrix形式是基于row的,因此能夠很高效的轉(zhuǎn)為csr,但是轉(zhuǎn)為csc效率相對較低。

強(qiáng)烈建議不要直接使用NumPy函數(shù)運(yùn)算稀疏矩陣

如果你想將NumPy函數(shù)應(yīng)用于這些矩陣,首先要檢查SciPy是否有自己的給定稀疏矩陣類的實(shí)現(xiàn),或者首先將稀疏矩陣轉(zhuǎn)換為NumPy數(shù)組(使用類的toarray()方法)。

要執(zhí)行乘法或轉(zhuǎn)置等操作,首先將矩陣轉(zhuǎn)換為CSC或CSR格式,效率高

CSR格式特別適用于快速矩陣矢量產(chǎn)品

CSR,CSC和COO格式之間的所有轉(zhuǎn)換都是線性復(fù)雜度。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • Python 如何解決稀疏矩陣運(yùn)算
  • Python selenium模擬網(wǎng)頁點(diǎn)擊爬蟲交管12123違章數(shù)據(jù)
  • python中os.path.join()函數(shù)實(shí)例用法
  • python實(shí)現(xiàn)簡單的井字棋
  • python 實(shí)現(xiàn)體質(zhì)指數(shù)BMI計(jì)算

標(biāo)簽:安康 山西 崇左 長沙 喀什 山西 海南 濟(jì)南

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《python scipy 稀疏矩陣的使用說明》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266