如果我使用的是sparse.lil_matrix格式,如何轻松有效地从矩阵中删除列?
答案 0 :(得分:10)
更简单,更快捷。您可能甚至不需要转换为csr,但我只知道它与csr稀疏矩阵一起使用并且之间的转换不应该是一个问题。
from scipy import sparse
x_new = sparse.lil_matrix(sparse.csr_matrix(x)[:,col_list])
答案 1 :(得分: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中删除一行,因此我受到限制。这是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存储库。
答案 2 :(得分:4)
对于稀疏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格式使用矩阵时,这种选择很好。
答案 3 :(得分:2)
我是python的新手,所以我的回答可能是错的,但我想知道为什么类似下面的内容效率不高?
假设您的lil_matrix被称为mat,并且您要删除第i列:
mat=hstack( [ mat[:,0:i] , mat[:,i+1:] ] )
现在矩阵将变为coo_matrix,但你可以将它变回lil_matrix。
好的,我知道这必须在hstack中创建两个矩阵,然后才能对mat变量进行赋值,这样就可以让原始矩阵再加上一个,但我猜是否稀疏我认为应该没有任何内存问题(因为内存(和时间)是使用稀疏矩阵的全部原因)。
答案 4 :(得分: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作为输入 - 也许这对某些人有用。
答案 5 :(得分:0)
通过查看每个稀疏矩阵的注释,特别是在我们的情况下是csc矩阵,它具有文档中列出的以下优点[1]
如果您要删除列索引,只需使用切片。 对于删除行,使用csr矩阵,因为它在行切片中是有效的