python建立空矩阵_SciPy创建稀疏矩阵
3. SciPy創建稀疏矩陣
嚴格意義上講ndarray數據類型應屬數組而非矩陣,而matrix才是矩陣,這個在NumPy創建matrix一章里有講述,是最基本的矩陣matrix創建方法,忘記了可以回頭看看。
本章利用scipy.sparse模塊下的類提供創建稀疏矩陣的方法,例如bsr_matrix稀疏矩陣類。
什么是稀疏矩陣?按數據結構領域知名學者嚴老師的定義稀疏矩陣是一個矩陣里有小于5%非0數據的矩陣可以視為稀疏矩陣,如果矩陣的總數據量較大,完成存儲這個矩陣會有大量的0存儲,浪費空間,所以對稀疏矩陣的存儲有必要研究用少量的內存存儲稀疏矩陣,在數據結構里有時用三元組來解決。
3.1 coo_matrix類創建稀疏矩陣
接下來我們看看在SciPy里如何解決對稀疏矩陣的存儲?效率如何?
三元組,即ijv,記錄稀疏矩陣里的非零數據的行i、列j坐標以及值v三個數據。下面按三元組的方式來創建稀疏矩陣。
#coding:utf-8
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)
# 將list數據轉為array數組
rows = np.array(a)
print rows,"#rows"
cols = np.array(b)
print cols, "#cols"
v = np.array(c)
print v,"#values"
# coo_matrix函數生成稀疏矩陣
sparseM = ss.coo_matrix((v,(rows,cols)))
print sparseM, "#sparseM,", "shape is ", sparseM.shape
# todense將稀疏矩陣轉為完全陣
fullM = sparseM.todense()
print fullM, "#fullM,", "shape is ", fullM.shape
程序執行結果:
[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每次可能都不同,因為行、列、值都是隨機產生的。
有關coo_matrix稀疏矩陣的處理方法函數可以參考相應的幫助,示例里給出了一個todense函數的使用方法。
3.2 csc_matrix類創建稀疏矩陣
csc_matrix類提供了很多方法來創建稀疏矩陣。
1). 可以直接調用類的構造函數(參閱"類"一章下的__init__的解析)將一個數組或矩陣轉化為稀疏矩陣存儲。
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)
程序執行結果:
[[ 0. 0. 0. 0.]
[ 0. 0. 12. 0.]
[ 0. 0. 22. 0.]] # a
(1, 2) 12.0
(2, 2) 22.0 # csc_matrix
2).可以創建一個空的稀疏矩陣,即全0,然后通過索引賦值獲得一個非空的稀疏矩陣,但用csc_matrix這樣去做時SciPy建議改為lil_matrix更高效,見執行結果的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()
程序執行結果:
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). 三元組的方法創建稀疏矩陣,和coo_matrix類創建的方式一樣指定i、j、v,只需將3.1節的程序里的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創建稀疏矩陣
csc_matrix類,實際就是數據結構里按列存儲稀疏矩陣時,給出每列里非零個數,以及列里那幾行是非零值。
下面是官方文檔:
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()
程序執行結果:
array([[1, 0, 4],
[0, 0, 5],
[2, 3, 6]])
以下是解析這個例子:
#第0列
i = 0
# 0列那些行非0?
indices[indptr[i]:indptr[i+1]]
= indices[indptr[0]:indptr[1]]
= indices[0:2]
= [0, 2]
# 0列非零行對應的值
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]
# 對應的值
data[indptr[i]:indptr[i+1]]
= data[2:3]
= [4,5,6]
總結一下csc_matrix的各個參數含義,data是稀疏矩陣的值;indices給出各列非0數據所在的行號;indptr則是給出前i列非0元素個數:indptr[0]表示第0列前有0個,indptr[1]第1列前共有0列那么多個實際是第0列非0個數,indptr[2]在則是記錄了0、1列一共有多少個非0元素。
5). 思考一下如下的稀疏矩陣怎么用csc_matrix構造出來?
[[ 0. 0. 0. 0.]
[ 0. 0. 12. 0.]
[ 0. 0. 0. 22.]]
首先可以寫出data = [12, 22],然后給出行坐標indices = [1, 2] ,最后給出前n列的非零數值的個數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"
程序執行結果
(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類創建稀疏矩陣
csr_matrix類是按行存儲矩陣,和csc_matrix按列真好相對應。也有很多函數,就不多解釋了。
同樣是下面這個矩陣,怎樣用csr_matrix實現?
[[ 0. 0. 0. 0.]
[ 0. 0. 12. 0.]
[ 0. 0. 0. 22.]]
首先可以寫出data = [12, 22],然后給出列坐標indices = [2, 3] ,最后給出前n行的非0值個數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類創建稀疏矩陣
在理解了csr_matrix、csc_matrix類之后在看bsr_matrix類就不難了,這里的b是block的意思。csr_matrix、csc_matrix類是用data里的值去在indices和indptr確定的位置上填充一個數據,而bsr_matrix類,則是用一個矩陣x去填充這個位置的數據、0值位置用與x矩陣同型0矩陣填充,所以整個稀疏矩陣會擴大。
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"
程序執行結果如下:
(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比較簡單,在這里就不再繼續展示了。
總結
以上是生活随笔為你收集整理的python建立空矩阵_SciPy创建稀疏矩阵的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: dump java崩溃自动 不生成_一个
- 下一篇: python redis集群_Pytho