簡體   English   中英

如何有效地從稀疏矩陣中刪除列?

[英]How can I remove a column from a sparse matrix efficiently?

如果我使用的是sparse.lil_matrix格式,如何輕松有效地從矩陣中刪除列?

更簡單,更快捷。 您可能甚至不需要轉換為csr,但我只知道它與csr稀疏矩陣一起工作並且之間的轉換應該不是問題。

from scipy import sparse

x_new = sparse.lil_matrix(sparse.csr_matrix(x)[:,col_list])

我一直都想要這個,事實上還沒有一個很好的內置方法來做到這一點。 這是一種方法。 我選擇創建lil_matrix的子類並添加remove_col函數。 如果需要,可以將removecol函數添加到lib/site-packages/scipy/sparse/lil.py文件中的lil_matrix類。 這是代碼:

from scipy import sparse
from bisect import bisect_left

class lil2(sparse.lil_matrix):
    def removecol(self,j):
        if j < 0:
            j += self.shape[1]

        if j < 0 or j >= self.shape[1]:
            raise IndexError('column index out of bounds')

        rows = self.rows
        data = self.data
        for i in xrange(self.shape[0]):
            pos = bisect_left(rows[i], j)
            if pos == len(rows[i]):
                continue
            elif rows[i][pos] == j:
                rows[i].pop(pos)
                data[i].pop(pos)
                if pos == len(rows[i]):
                    continue
            for pos2 in xrange(pos,len(rows[i])):
                rows[i][pos2] -= 1

        self._shape = (self._shape[0],self._shape[1]-1)

我試過了,沒有看到任何錯誤。 我當然認為它比切出列更好,據我所知,這只是創建一個新矩陣。

我決定制作一個removerow功能,但我不認為它和removecol一樣好。 由於無法按照我想要的方式從ndarray中刪除一行,因此我受到限制。 這里是removerow,可以添加到上面的類

    def removerow(self,i):
        if i < 0:
            i += self.shape[0]

        if i < 0 or i >= self.shape[0]:
            raise IndexError('row index out of bounds')

        self.rows = numpy.delete(self.rows,i,0)
        self.data = numpy.delete(self.data,i,0)
        self._shape = (self._shape[0]-1,self.shape[1])

也許我應該將這些函數提交給Scipy存儲庫。

對於稀疏csr矩陣(X)和要刪除的索引列表(index_to_drop):

to_keep = list(set(xrange(X.shape[1]))-set(index_to_drop))    
new_X = X[:,to_keep]

將lil_matrices轉換為csr_matrices很容易。 檢查lil_matrix文檔中的 tocsr()

但請注意,使用tolil()從csr到lil矩陣的代價很高。 因此,當您不需要以lil格式使用矩陣時,這種選擇很好。

我是python的新手,所以我的答案可能是錯的,但我想知道為什么像下面這樣的東西效率不高?

假設您的lil_matrix被稱為mat,並且您要刪除第i列:

mat=hstack( [ mat[:,0:i] , mat[:,i+1:] ] )

現在矩陣將轉向一個coo_matrix,但你可以把它變回lil_matrix。

好吧,據我所知,這必須在hstack中創建兩個矩陣,然后才能對mat變量進行賦值,這樣就可以讓原始矩陣再加上一個矩陣,但我想如果稀疏度足夠大那么我認為應該沒有任何內存問題(因為內存(和時間)是使用稀疏矩陣的全部原因)。


def removecols(W, col_list):
        if min(col_list) = W.shape[1]:
                raise IndexError('column index out of bounds')
        rows = W.rows
        data = W.data
        for i in xrange(M.shape[0]):
            for j in col_list:
                pos = bisect_left(rows[i], j)
                if pos == len(rows[i]):
                        continue
                elif rows[i][pos] == j:
                        rows[i].pop(pos)
                        data[i].pop(pos)
                        if pos == len(rows[i]):
                                continue
                for pos2 in xrange(pos,len(rows[i])):
                        rows[i][pos2] -= 1
        W._shape = (W._shape[0], W._shape[1]-len(col_list))
        return W

只需重寫您的代碼以使用col_list作為輸入 - 也許這對某些人有用。

通過查看每個稀疏矩陣的注釋,特別是在我們的情況下是csc矩陣,它具有文檔[1]中列出的以下優點

  • 高效算術運算CSC + CSC,CSC * CSC等
  • 有效的列切片
  • 快速矩陣矢量積(CSR,BSR可能更快)

如果您要刪除列索引,只需使用切片。 對於刪除行,請使用csr矩陣,因為它在行切片中很有效

暫無
暫無

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

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