代码之家  ›  专栏  ›  技术社区  ›  Brandon Pelfrey

如何有效地从稀疏矩阵中移除列?

  •  13
  • Brandon Pelfrey  · 技术社区  · 15 年前

    如果我使用的是sparse.lil_矩阵格式,如何轻松高效地从矩阵中删除列?

    6 回复  |  直到 8 年前
        1
  •  7
  •   Justin Peel    15 年前

    我一直想自己做这件事,事实上,还没有一个很好的内置方式来做这件事。这是一种方法。我选择创建lil_matrix的一个子类并添加remove_col函数。如果需要,可以将removecol函数添加到 lib/site-packages/scipy/sparse/lil.py 文件。代码如下:

    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)
    

    我试过了,没发现什么虫子。我当然认为这比把列切掉要好,就我所知,这只是创建了一个新的矩阵。

    我决定也做一个removeow功能,但我认为它不如removecol好。我无法按我所希望的方式从ndarray中删除一行,这限制了我的工作。这里是removeow,可以添加到上面的类中

        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
  •  9
  •   Newmu    12 年前

    更简单更快。您甚至可能不需要转换为csr,但我只知道它与csr稀疏矩阵一起工作,并且在两者之间转换不应该是一个问题。

    from scipy import sparse
    
    x_new = sparse.lil_matrix(sparse.csr_matrix(x)[:,col_list])
    
        3
  •  3
  •   JRun    10 年前

    对于稀疏的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 documentation

    但是,请注意,使用to lil()从csr到lil矩阵是昂贵的。所以,当您不需要使用LIL格式的矩阵时,这个选择是很好的。

        4
  •  2
  •   nobody    13 年前

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

    假设您的lil_矩阵称为mat,并且您希望删除i列:

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

    在那之后矩阵会变成一个coo_矩阵,但是你可以把它变成lil_矩阵。

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

        5
  •  0
  •   Daniel    12 年前
    
    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作为输入-也许这对某些人有帮助。

        6
  •  0
  •   user1443317    8 年前

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

    • 高效的算术运算csc+csc,csc*csc等。
    • 高效柱切片
    • 快速矩阵向量产品(CSR、BSR可能更快)

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