17

如果我使用 sparse.lil_matrix 格式,如何轻松有效地从矩阵中删除一列?

4

6 回答 6

12

更简单,更快。您甚至可能不需要转换为 csr,但我只是确定它可以与 csr 稀疏矩阵一起使用,并且之间的转换应该不是问题。

from scipy import sparse

x_new = sparse.lil_matrix(sparse.csr_matrix(x)[:,col_list])
于 2013-06-19T23:14:18.047 回答
8

我自己一直想要这个,事实上还没有一个很好的内置方法来做到这一点。这是一种方法。我选择创建一个 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 存储库。

于 2010-03-03T06:10:03.380 回答
8

对于稀疏 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 格式时,此选择是不错的选择。

于 2015-06-29T18:00:36.813 回答
2

我是 python 新手,所以我的回答可能是错误的,但我想知道为什么下面这样的东西不会有效?

假设您的 lil_matrix 称为 mat 并且您要删除第 i 列:

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

现在矩阵将在此之后变为 coo_matrix,但您可以将其转回 lil_matrix。

好的,我知道这将不得不在 hstack 中创建两个矩阵,然后再分配给 mat 变量,所以它就像同时拥有原始矩阵加上一个矩阵一样,但我想如果稀疏性足够大那么我认为不应该有任何内存问题(因为内存(和时间)是使用稀疏矩阵的全部原因)。

于 2012-05-30T22:18:31.083 回答
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 作为输入 - 也许这对某人有帮助。

于 2010-06-03T12:39:45.207 回答
0

通过查看每个稀疏矩阵的注释,特别是在我们的例子中是 csc 矩阵,它具有文档[1]中列出的以下优点

  • 高效算术运算 CSC + CSC、CSC * CSC 等
  • 高效的列切片
  • 快速矩阵向量积(CSR、BSR 可能更快)

如果您有要删除的列索引,只需使用切片。对于删除行使用 csr 矩阵,因为它在行切片中很有效

于 2016-12-26T08:45:26.460 回答