2010-03-03 103 views

回答

7

我一直想要這個自己,事實上還沒有一個偉大的內置方式來做到這一點呢。這是一種方法。我選擇了製作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中刪除一行。這裏是一個可以添加到上面的類

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的庫removerow。

0

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作爲輸入 - 也許這對別人會有幫助。

+1

我很高興有人試圖改善我的第一次嘗試。但是,如果min(col_list)= W.shape [1]:'在很多方面對我沒有意義。首先,在Python中的if參數中使用賦值是無效的語法。其次,你爲什麼用形狀檢查col_list的最小值?我在想,也許你打算做'如果max(col_list)> = W.shape [1]:'?當然,這意味着你也不能使用負指數,也不會檢查指數是否低於0以及如何處理它們。 – 2010-06-03 17:27:38

1

我是新來的python所以我的答案可能是錯誤的,但我想知道爲什麼像下面的東西不會有效?

比方說你lil_matrix被稱爲墊和要刪除第i列:

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

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

好吧,據我所知,這將不得不在創建兩個矩陣內部的堆棧之前,它分配給mat變量,所以它會像原來的矩陣加上一個更多的同時,但我猜如果稀疏性足夠大,我認爲不應該有任何記憶問題(因爲記憶(和時間)是使用稀疏矩陣的全部原因)。

+0

這看起來像一個問題而不是答案。 – 2012-10-21 01:54:01

8

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

from scipy import sparse 

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

這不適合我。 – kevin 2014-12-18 20:59:02

+2

爲什麼使用CSR(壓縮稀疏行)矩陣進行列分割? CSR格式的一個缺點是「慢柱切片操作(考慮CSC)」(根據scipy文檔)。你可能應該使用'csc_matrix'轉換。 – silentser 2017-03-09 11:08:14

1

對於稀疏矩陣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 documentation中檢查tocsr()

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

0

通過我們的情況看筆記每個稀疏矩陣,特別是CSC矩陣它具有以下優點,如文檔中列出的[1]

  • 高效算術運算CSC + CSC,CSC * CSC等。
  • 高效柱切
  • 快速矩陣向量積(CSR,BSR可能會更快)

如果您有西澳列索引nt刪除,只需使用切片。 對於刪除行使用csr矩陣,因爲它是行劃分高效的