2010-03-03 54 views

Trả lời

7

Tôi đã muốn điều này bản thân mình và trong sự thật không có một cách tích hợp tuyệt vời để làm điều đó được nêu ra. Đây là một cách để làm điều đó. Tôi đã chọn tạo một lớp con của lil_matrix và thêm hàm remove_col. Nếu bạn muốn, thay vào đó bạn có thể thêm hàm removeecol vào lớp lil_matrix trong tệp lib/site-packages/scipy/sparse/lil.py của bạn. Đây là mã:

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) 

Tôi đã dùng thử và không thấy bất kỳ lỗi nào. Tôi chắc chắn nghĩ rằng nó là tốt hơn so với cắt cột ra, mà chỉ cần tạo ra một ma trận mới theo như tôi biết.

Tôi cũng đã quyết định thực hiện chức năng xóa bỏ, nhưng tôi không nghĩ rằng nó hoạt động tốt như removecol. Tôi bị giới hạn bởi việc không thể xóa một hàng khỏi một ndarray theo cách mà tôi muốn. Đây là loại bỏ có thể được thêm vào lớp trên

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]) 

Có lẽ tôi nên gửi các chức năng này vào kho lưu trữ Scipy.

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 

Chỉ cần viết lại mã của bạn để làm việc với col_list làm đầu vào - có thể điều này sẽ hữu ích cho ai đó.

+1

Tôi rất vui vì ai đó đang cố gắng cải thiện trong lần thử đầu tiên của tôi. Tuy nhiên, dòng 'if min (col_list) = W.shape [1]:' không có ý nghĩa với tôi theo nhiều cách. Đầu tiên, cú pháp không hợp lệ để sử dụng một phép gán trong một đối số if trong Python. Thứ hai, tại sao bạn kiểm tra min của col_list với hình dạng? Tôi nghĩ rằng có lẽ bạn muốn làm 'nếu max (col_list)> = W.shape [1]:'? Tất nhiên, điều đó có nghĩa là bạn không thể sử dụng các chỉ số tiêu cực và không có bất kỳ kiểm tra nào cho các chỉ số dưới 0 và phải làm gì với chúng. –

1

Tôi mới dùng python nên câu trả lời của tôi có thể sai, nhưng tôi đã tự hỏi tại sao một số thứ như sau sẽ không hiệu quả?

phép nói rằng lil_matrix của bạn được gọi mat và rằng bạn muốn loại bỏ các thứ i cột:

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

Bây giờ ma trận sẽ chuyển sang một coo_matrix sau đó nhưng bạn có thể biến nó trở lại lil_matrix. Ok, tôi hiểu rằng điều này sẽ phải tạo ra hai ma trận bên trong hstack trước khi nó chuyển nhượng cho biến mat để nó sẽ giống như có ma trận ban đầu cộng thêm một ma nữa cùng một lúc nhưng tôi đoán nếu sparsity là đủ lớn sau đó tôi nghĩ rằng không nên có bất kỳ vấn đề bộ nhớ (kể từ khi bộ nhớ (và thời gian) là toàn bộ lý do của việc sử dụng ma trận thưa thớt).

+0

Điều này trông giống như một câu hỏi không phải là câu trả lời. –

8

Đơn giản hơn và nhanh hơn nhiều. Bạn thậm chí có thể không cần chuyển đổi sang csr, nhưng tôi chỉ biết chắc chắn rằng nó hoạt động với các ma trận thưa thớt csr và chuyển đổi giữa không phải là một vấn đề.

from scipy import sparse 

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

Điều này không hiệu quả đối với tôi. – kevin

+2

Tại sao bạn sử dụng ma trận CSR (hàng thưa thớt nén) để cắt cột? Một trong những nhược điểm của định dạng CSR là 'hoạt động cắt lát chậm (xem xét CSC)' (theo tài liệu scipy). Bạn nên, có lẽ, sử dụng 'csc_matrix' chuyển đổi để thay thế. – silentser

1

Đối với một ma trận thưa thớt csr (X) và một danh sách các chỉ số để thả (index_to_drop):

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

Nó rất dễ dàng để chuyển đổi lil_matrices để csr_matrices. Kiểm tra tocsr() trong lil_matrix documentation

Lưu ý rằng việc chuyển từ các ma trận csr sang lil bằng tolil() rất tốn kém. Vì vậy, sự lựa chọn này là tốt khi bạn không cần phải có ma trận của bạn trong định dạng lil.

0

Bằng cách nhìn vào các ghi chú cho mỗi ma trận thưa thớt, đặc biệt là trong trường hợp của chúng tôi là ma trận csc nó có những ưu điểm sau như được liệt kê trong tài liệu [1]

  • phép tính số học hiệu quả CSC + CSC, CSC * CSC, vv .
  • cột hiệu quả slicing
  • sản phẩm vector ma trận nhanh (CSR, BSR có thể nhanh hơn)

Nếu bạn có các chỉ số cột bạn wa nt để loại bỏ, chỉ cần sử dụng slicing. Để xóa các hàng sử dụng ma trận csr vì nó có hiệu quả trong việc cắt hàng

Các vấn đề liên quan