python建立空矩阵_SciPy创建稀疏矩阵
3. SciPy創(chuàng)建稀疏矩陣
嚴(yán)格意義上講ndarray數(shù)據(jù)類型應(yīng)屬數(shù)組而非矩陣,而matrix才是矩陣,這個(gè)在NumPy創(chuàng)建matrix一章里有講述,是最基本的矩陣matrix創(chuàng)建方法,忘記了可以回頭看看。
本章利用scipy.sparse模塊下的類提供創(chuàng)建稀疏矩陣的方法,例如bsr_matrix稀疏矩陣類。
什么是稀疏矩陣?按數(shù)據(jù)結(jié)構(gòu)領(lǐng)域知名學(xué)者嚴(yán)老師的定義稀疏矩陣是一個(gè)矩陣?yán)镉行∮?%非0數(shù)據(jù)的矩陣可以視為稀疏矩陣,如果矩陣的總數(shù)據(jù)量較大,完成存儲(chǔ)這個(gè)矩陣會(huì)有大量的0存儲(chǔ),浪費(fèi)空間,所以對(duì)稀疏矩陣的存儲(chǔ)有必要研究用少量的內(nèi)存存儲(chǔ)稀疏矩陣,在數(shù)據(jù)結(jié)構(gòu)里有時(shí)用三元組來解決。
3.1 coo_matrix類創(chuàng)建稀疏矩陣
接下來我們看看在SciPy里如何解決對(duì)稀疏矩陣的存儲(chǔ)?效率如何?
三元組,即ijv,記錄稀疏矩陣?yán)锏姆橇銛?shù)據(jù)的行i、列j坐標(biāo)以及值v三個(gè)數(shù)據(jù)。下面按三元組的方式來創(chuàng)建稀疏矩陣。
#coding:utf-8
import numpy as np
import scipy.sparse as ss
import random
# 隨機(jī)產(chǎn)生行、列坐標(biāo)和值
a = random.sample(range(0, 9), 5)
b = random.sample(range(0, 9), 5)
c = random.sample(range(1, 100), 5)
# 將list數(shù)據(jù)轉(zhuǎn)為array數(shù)組
rows = np.array(a)
print rows,"#rows"
cols = np.array(b)
print cols, "#cols"
v = np.array(c)
print v,"#values"
# coo_matrix函數(shù)生成稀疏矩陣
sparseM = ss.coo_matrix((v,(rows,cols)))
print sparseM, "#sparseM,", "shape is ", sparseM.shape
# todense將稀疏矩陣轉(zhuǎn)為完全陣
fullM = sparseM.todense()
print fullM, "#fullM,", "shape is ", fullM.shape
程序執(zhí)行結(jié)果:
[8 0 6 7 4] #rows
[3 8 1 2 7] #cols
[ 1 48 99 62 94] #values
(8, 3) 1
(0, 8) 48
(6, 1) 99
(7, 2) 62
(4, 7) 94 #sparseM, shape is (9, 9)
[[ 0 0 0 0 0 0 0 0 48]
[ 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 94 0]
[ 0 0 0 0 0 0 0 0 0]
[ 0 99 0 0 0 0 0 0 0]
[ 0 0 62 0 0 0 0 0 0]
[ 0 0 0 1 0 0 0 0 0]] #fullM, shape is (9, 9)
需主要sparseM和fullM每次可能都不同,因?yàn)樾小⒘小⒅刀际请S機(jī)產(chǎn)生的。
有關(guān)coo_matrix稀疏矩陣的處理方法函數(shù)可以參考相應(yīng)的幫助,示例里給出了一個(gè)todense函數(shù)的使用方法。
3.2 csc_matrix類創(chuàng)建稀疏矩陣
csc_matrix類提供了很多方法來創(chuàng)建稀疏矩陣。
1). 可以直接調(diào)用類的構(gòu)造函數(shù)(參閱"類"一章下的__init__的解析)將一個(gè)數(shù)組或矩陣轉(zhuǎn)化為稀疏矩陣存儲(chǔ)。
import numpy as np
import scipy.sparse as ss
a = np.zeros((3, 4))
a[1, 2] = 12
a[2, 2] = 22
print a
print ss.csc_matrix(a)
程序執(zhí)行結(jié)果:
[[ 0. 0. 0. 0.]
[ 0. 0. 12. 0.]
[ 0. 0. 22. 0.]] # a
(1, 2) 12.0
(2, 2) 22.0 # csc_matrix
2).可以創(chuàng)建一個(gè)空的稀疏矩陣,即全0,然后通過索引賦值獲得一個(gè)非空的稀疏矩陣,但用csc_matrix這樣去做時(shí)SciPy建議改為lil_matrix更高效,見執(zhí)行結(jié)果的warning信息。
import scipy.sparse as ss
x = ss.csc_matrix((4, 3))
#x = ss.lil_matrix((4, 3))
print "x --"
print x
x[1, 2] = 12
x[3, 1] = 23
print x
print x.todense()
程序執(zhí)行結(jié)果:
x --
/usr/lib/python2.7/dist-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csc_matrix is expensive. lil_matrix is more efficient.
SparseEfficiencyWarning)
(3, 1) 23.0
(1, 2) 12.0
[[ 0. 0. 0.]
[ 0. 0. 12.]
[ 0. 0. 0.]
[ 0. 23. 0.]]
3). 三元組的方法創(chuàng)建稀疏矩陣,和coo_matrix類創(chuàng)建的方式一樣指定i、j、v,只需將3.1節(jié)的程序里的coo_matrix改為csc_matrix即可。
import numpy as np
import scipy.sparse as ss
import random
a = random.sample(range(0, 9), 5)
b = random.sample(range(0, 9), 5)
c = random.sample(range(1, 100), 5)
rows = np.array(a)
print rows,"#rows"
cols = np.array(b)
print cols, "#cols"
v = np.array(c)
print v,"#values"
sparseM = ss.csc_matrix((v,(rows,cols)))
print sparseM, "#sparseM,", "shape is ", sparseM.shape
fullM = sparseM.todense()
print fullM, "#fullM,", "shape is ", fullM.shape
print sparseM.sum(), sparseM.nonzero()
print sparseM.get_shape()
4). 真正的csc_matrix創(chuàng)建稀疏矩陣
csc_matrix類,實(shí)際就是數(shù)據(jù)結(jié)構(gòu)里按列存儲(chǔ)稀疏矩陣時(shí),給出每列里非零個(gè)數(shù),以及列里那幾行是非零值。
下面是官方文檔:
csc_matrix((data, indices, indptr), [shape=(M, N)])
is the standard CSC representation where the row indices for column i are stored in indices[indptr[i]:indptr[i+1]] and their corresponding values are stored in data[indptr[i]:indptr[i+1]]. If the shape parameter is not supplied, the matrix dimensions are inferred from the index arrays.
官方例子:
import numpy as np
from scipy.sparse import csc_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])
print csc_matrix((data, indices, indptr), shape=(3, 3)).toarray()
程序執(zhí)行結(jié)果:
array([[1, 0, 4],
[0, 0, 5],
[2, 3, 6]])
以下是解析這個(gè)例子:
#第0列
i = 0
# 0列那些行非0?
indices[indptr[i]:indptr[i+1]]
= indices[indptr[0]:indptr[1]]
= indices[0:2]
= [0, 2]
# 0列非零行對(duì)應(yīng)的值
data[indptr[i]:indptr[i+1]]
= data[indptr[0]:indptr[1]]
= data[0:2]
= [1, 2]
i = 1
indices[indptr[i]:indptr[i+1]]
= indices[indptr[1]:indptr[2]]
= indices[1:2]
= [2]
data[indptr[i]:indptr[i+1]]
= data[indptr[1]:indptr[2]]
= data[2:3]
= [3]
# 第2列
i = 2
# 非0行?
indices[indptr[i]:indptr[i+1]]
= indices[indptr[2]:indptr[3]]
= indices[3:6]
= [0, 1, 2]
# 對(duì)應(yīng)的值
data[indptr[i]:indptr[i+1]]
= data[2:3]
= [4,5,6]
總結(jié)一下csc_matrix的各個(gè)參數(shù)含義,data是稀疏矩陣的值;indices給出各列非0數(shù)據(jù)所在的行號(hào);indptr則是給出前i列非0元素個(gè)數(shù):indptr[0]表示第0列前有0個(gè),indptr[1]第1列前共有0列那么多個(gè)實(shí)際是第0列非0個(gè)數(shù),indptr[2]在則是記錄了0、1列一共有多少個(gè)非0元素。
5). 思考一下如下的稀疏矩陣怎么用csc_matrix構(gòu)造出來?
[[ 0. 0. 0. 0.]
[ 0. 0. 12. 0.]
[ 0. 0. 0. 22.]]
首先可以寫出data = [12, 22],然后給出行坐標(biāo)indices = [1, 2] ,最后給出前n列的非零數(shù)值的個(gè)數(shù)indptr = [0,0,0,1,2]。
import numpy as np
from scipy.sparse import csc_matrix
indptr = np.array([0,0,0,1,2])
indices = np.array([1, 2])
data = np.array([12, 22])
csc = csc_matrix((data, indices, indptr), shape=(3, 4))
print csc, "#csc"
print csc.todense(), "#csc.todense"
程序執(zhí)行結(jié)果
(1, 2) 12
(2, 3) 22 #csc
[[ 0 0 0 0]
[ 0 0 12 0]
[ 0 0 0 22]] #csc.todense
3.3 csr_matrix類創(chuàng)建稀疏矩陣
csr_matrix類是按行存儲(chǔ)矩陣,和csc_matrix按列真好相對(duì)應(yīng)。也有很多函數(shù),就不多解釋了。
同樣是下面這個(gè)矩陣,怎樣用csr_matrix實(shí)現(xiàn)?
[[ 0. 0. 0. 0.]
[ 0. 0. 12. 0.]
[ 0. 0. 0. 22.]]
首先可以寫出data = [12, 22],然后給出列坐標(biāo)indices = [2, 3] ,最后給出前n行的非0值個(gè)數(shù)indptr = [0,0,1,2]。
程序如下:
import numpy as np
from scipy.sparse import csr_matrix
indptr = np.array([0,0,1,2])
indices = np.array([2,3])
data = np.array([12, 22])
csr = csr_matrix((data, indices, indptr), shape=(3, 4))
print csr, "#csr"
print csr.todense(), "#csr.todense"
3.4 bsr_matrix類創(chuàng)建稀疏矩陣
在理解了csr_matrix、csc_matrix類之后在看bsr_matrix類就不難了,這里的b是block的意思。csr_matrix、csc_matrix類是用data里的值去在indices和indptr確定的位置上填充一個(gè)數(shù)據(jù),而bsr_matrix類,則是用一個(gè)矩陣x去填充這個(gè)位置的數(shù)據(jù)、0值位置用與x矩陣同型0矩陣填充,所以整個(gè)稀疏矩陣會(huì)擴(kuò)大。
import numpy as np
from scipy.sparse import bsr_matrix
indptr = np.array([0,0,1,2])
indices = np.array([2,3])
data = np.array([12, 22]).repeat(6).reshape(2, 2, 3)
bsr = bsr_matrix((data, indices, indptr), shape=(6, 12))
print bsr, "#bsr"
print bsr.todense(), "#bsr.todense"
程序執(zhí)行結(jié)果如下:
(2, 6) 12
(2, 7) 12
(2, 8) 12
(3, 6) 12
(3, 7) 12
(3, 8) 12
(4, 9) 22
(4, 10) 22
(4, 11) 22
(5, 9) 22
(5, 10) 22
(5, 11) 22 #bsr
[[ 0 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 12 12 12 0 0 0]
[ 0 0 0 0 0 0 12 12 12 0 0 0]
[ 0 0 0 0 0 0 0 0 0 22 22 22]
[ 0 0 0 0 0 0 0 0 0 22 22 22]] #bsr.todense
3.5 其他稀疏矩類
scipy.sparse里還有dia_matrix 、dok_matrix比較簡(jiǎn)單,在這里就不再繼續(xù)展示了。
總結(jié)
以上是生活随笔為你收集整理的python建立空矩阵_SciPy创建稀疏矩阵的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: dump java崩溃自动 不生成_一个
- 下一篇: python redis集群_Pytho