簡體   English   中英

在python中將稀疏向量添加到稀疏數組太慢

[英]Adding a sparse vector to a sparse array in python is too slow

我有一個稀疏矩陣,我想向它添加一個稀疏向量。 我嘗試了不同的稀疏格式,包括csr,csc,lil,coo,以及將稀疏矢量添加到稀疏矩陣的不同方式,包括vstack和concatenate。

事實證明,所有方式和格式都很慢。 但是,當我將向量轉換為密集格式(通過todense())並將其附加到密集矩陣(特別是numpy.ndarray)時,它可以很快完成。 為什么? 是否有我不知道的技巧或合適的格式?

這是我嘗試使用“ coo”格式的代碼時的代碼:

from scipy.sparse import coo_matrix, rand
from time import time as timer
from numpy import array, concatenate, empty

### sparse appending in coo way ####
def sparse_append(A):
    dim = A.shape[1]
    mat = coo_matrix((0, dim))

    sparse_addtime = 0

    for vector in A:
        st = timer() 

        row = coo_matrix(vector)
        newdata = concatenate((mat.data, row.data))
        newrows = concatenate((mat.row, row.row + mat.shape[0]))
        newcols = concatenate((mat.col, row.col))

        mat = coo_matrix((newdata, (newrows, newcols)), shape = ((mat.shape)[0]+1, (mat.shape)[1]))

        et = timer() 
        sparse_addtime += et-st

    return sparse_addtime

#### dense append ####
def dense_append(A):
    dim = A.shape[1]
    mat = empty([0,dim])

    dense_addtime = 0

    for vector in A:
        st = timer()
        mat = concatenate((mat,vector))
        et = timer()
        dense_addtime += et-st

    return dense_addtime



### main ####
if __name__ == '__main__':
    dim = 400
    n = 200

    A = rand(n, dim, density = 0.1, format='lil')
    B = A.todense() #numpy.ndarray

    t1 = sparse_append(A)
    t2 = dense_append(B)

    print t1, t2

任何幫助表示贊賞。

稀疏附加代碼中最慢的部分是行轉換。

row = coo_matrix(vector)

我運行它大約需要花費65%的時間。 這是因為它需要更改用於存儲數據的存儲格式。另一個較慢的部分是創建矩陣。

mat = coo_matrix((newdata, (newrows, newcols)), shape = ((mat.shape)[0]+1, (mat.shape)[1]))

這還需要30%的時間。 每次執行此操作時,您都將復制所有數據並分配一堆內存。 添加行(尤其是如果行已經為lil格式)的最有效方法是修改矩陣。 如果您一開始就知道矩陣的尺寸,則可以從一開始就以正確的形狀創建矩陣。 稀疏格式提高了內存效率,並且沒有空行。 否則,您可以每次使用set_shape來增加尺寸。

from scipy.sparse import lil_matrix, rand
from time import time as timer
from numpy import array, concatenate, empty

### sparse appending ####
def sparse_append(A):
    dim = A.shape[1]
    mat = lil_matrix(A.shape, dtype = A.dtype)

    sparse_addtime = 0
    i = 0
    for vector in A:
        st = timer()

        mat[i] = vector
        i += 1
        et = timer() 
        sparse_addtime += et-st

    return sparse_addtime



#### dense append ####
def dense_append(A):
    dim = A.shape[1]
    mat = empty([0,dim])

    dense_addtime = 0

    for vector in A:
        st = timer()
        mat = concatenate((mat,vector))
        et = timer()
        dense_addtime += et-st

    return dense_addtime



### main ####
if __name__ == '__main__':
    dim = 400
    n = 200

    A = rand(n, dim, density = 0.1, format='lil')
    B = A.todense() #numpy.ndarray

    t1 = sparse_append(A)
    t2 = dense_append(B)

    print t1, t2

像這樣運行代碼,從稀疏添加中我得到了明顯更好的時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM