如何高效地从稀疏矩阵中移除一列?
如果我在使用sparse.lil_matrix格式,怎么才能简单又高效地删除矩阵中的一列呢?
6 个回答
8
对于一个稀疏的csr矩阵(X)和一个要删除的索引列表(index_to_drop):
to_keep = list(set(xrange(X.shape[1]))-set(index_to_drop))
new_X = X[:,to_keep]
把lil矩阵转换成csr矩阵是很简单的。你可以查看tocsr(),了解更多关于lil_matrix的文档。
不过要注意,从csr矩阵转换回lil矩阵(使用tolil())是比较耗费资源的。所以,如果你不需要把矩阵放在lil格式,这种选择是不错的。
12
这方法简单又快。你可能甚至不需要把数据转换成csr格式,但我可以肯定的是,它在csr稀疏矩阵上是有效的,转换格式应该不会有问题。
from scipy import sparse
x_new = sparse.lil_matrix(sparse.csr_matrix(x)[:,col_list])
8
我一直想要这个功能,实际上目前还没有很好的内置方法来实现。这里有一个解决办法。我选择创建一个名为 lil_matrix 的子类,并添加一个叫做 remove_col 的函数。如果你愿意,也可以直接在你的 lib/site-packages/scipy/sparse/lil.py
文件中给 lil_matrix 类添加 removecol 函数。以下是代码:
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 的代码库里。