稀疏矩陣及其應用案例

稀疏矩陣

  • 稀疏矩陣的類別
  • 稀疏矩陣的L2範數計算
  • 合併兩個行向量

目錄

稀疏矩陣

本節介紹python的scipy.sparse中提供的稀疏矩陣,如下
- bsr_matrix, short for Block Sparse Row matrix.
- coo_matrix, short for A sparse matrix in COOrdinate format.
- csc_matrix, short for Compressed Sparse Column matrix.
- csr_matrix, short for Compressed Sparse Row matrix.
- dia_matri, short for Sparse matrix with DIAgonal storage.
- dok_matrix, short for Dictionary Of Keys based sparse matrix.
- lil_matrix, short for Row-based linked list sparse matrix
- spmatrix
你可以參考文獻 [ 官方文檔 ]

PS:如果這個鏈接過時,可以google搜索關鍵字”Spicy.sparse”,第一個結果就是這個官方文檔。
我只用了壓縮稀疏行矩陣(csr_matrix),理由是每個不同種的矩陣都提供了相互轉換的方法,比如csr_matrix,提供了csr_matrix.tocoo()函數,可以實現將一個csr_matrix矩陣,轉換成coo_matrix形式的矩陣。例如,

def convert():
    from scipy.sparse import csr_matrix
    sparsev = csr_matrix([0, 2, 0, 0])
    print type(sparsev)
    sparseCoo = sparsev.tocoo()
    print type(sparseCoo)
>>> convert()

輸出如下結果:

<class 'scipy.sparse.csr.csr_matrix'>
<class 'scipy.sparse.coo.coo_matrix'>

應用I, 稀疏矩陣的L2範數計算

雖然scipy的lingalg(i.e., scipy.sparse.linalg.norm)提供了各種計算範數的函數,可參考文獻 [ linalg.norm官方文檔 ]

貌似不能直接從稀疏矩陣或稀疏向量直接計算。由於我的稀疏向量的維數是4w左右,用先轉換成ndarray的形式後,再計算太耗時了,所以就自己寫了函數計算L2範數。
代碼如下:

###稀疏矩陣實現, compute L2 via csr_matrix的操作
def getL2SparseConcise(diffSparseVector):
    temp = csr_matrix.multiply(diffSparseVector, diffSparseVector)
    L2 = temp.sum(axis=1).tolist()[0][0]
    return np.sqrt(L2)

###norm實現, convert csr_matrix vector to a ndarray, and compute L2
def getL2ViaNorm(diffSparseVector):
    from scipy.sparse.linalg import norm
    denseDSV = np.array(convertSparse2List(diffSparseVector))
    tempDense = norm(csr_matrix(denseDSV))
    return np.sqrt(tempDense)
###ndarray實現,
def getL2Dense(diffSparseVector):
    ## verify dense
    denseDSV = np.array(convertSparse2List(diffSparseVector))
    tempDense = denseDSV.dot(denseDSV)
    return np.sqrt(tempDense)

你可以從我的git上下載源文件 [ git 源文件 ].

運行,並查看直接用稀疏矩陣進行計算和通過轉換成ndarray的dense矩陣然後計算的差異。
結論如下:

時間上用稀疏矩陣直接計算是很高效的。在時間上, 稀疏矩陣實現比norm實現(getL2ViaNorm function)快,norm實現(getL2ViaNorm function)比ndarray實現快。
norm的L2計算有問題,貌似開了兩次根號。

應用II,合併兩個行向量

我需要把兩個稀疏的向量合併成一個矩陣,受文獻3指導。
核心思想

調用稀疏矩陣的vstack,可以把兩個向量,按照行合併成一個矩陣。
調用稀疏矩陣的hstack,可以把兩個向量,按照列合併成一個矩陣

由於這方法,類似,就舉出按照行合併的例子。

def incrementalBuildByRow(rowA, rowB):
    from scipy.sparse import vstack
    rowUnion = vstack([rowA, rowB])
    return rowUnion

## test code:
def incrementalBuildByRowTest():
    from scipy.sparse import csr_matrix
    sparsev1 = csr_matrix([0, 2, 0, 0])
    sparsev2 = csr_matrix([2, 0, 1, 0])
    ll = incrementalBuildByRow(sparsev1, sparsev2)
    print "type", type(ll)
    print ll.todense()

if __name__ == "__main__":
    incrementalBuildByRowTest()

輸出結果是

type <class 'scipy.sparse.csr.csr_matrix'>
[[0 2 0 0]
 [2 0 1 0]]

[1]: 官方文檔 https://docs.scipy.org/doc/scipy/reference/sparse.html
[2]: 稀疏矩陣的存儲格式 http://blog.csdn.net/anshan1984/article/details/8580952
[3]: scipy矩陣操作 http://blog.csdn.net/nkwangjie/article/details/17502443
[4]: vstack manual https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.vstack.html#scipy.sparse.vstack
[5]: hstack manual https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.hstack.html#scipy.sparse.hstack

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章