首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >稀疏矩阵是否存在numpy.delete()等效项?

稀疏矩阵是否存在numpy.delete()等效项?
EN

Stack Overflow用户
提问于 2012-10-26 05:24:33
回答 6查看 17K关注 0票数 25

假设我有一个二维矩阵作为numpy数组。如果我想删除这个矩阵中具有特定索引的行,我会使用numpy.delete()。下面是我的意思的一个例子:

代码语言:javascript
复制
In [1]: my_matrix = numpy.array([
   ...:     [10, 20, 30, 40, 50],
   ...:     [15, 25, 35, 45, 55],
   ...:     [95, 96, 97, 98, 99]
   ...: ])
In [2]: numpy.delete(my_matrix, [0, 2], axis=0)
Out[2]: array([[15, 25, 35, 45, 55]])

我正在寻找一种方法来处理scipy.sparse包中的矩阵。我知道可以通过将整个矩阵转换为numpy数组来做到这一点,但我不想这样做。有没有其他方法可以做到这点?

非常感谢!

EN

回答 6

Stack Overflow用户

发布于 2012-10-26 07:21:58

对于CSR来说,这可能是最有效的方式:

代码语言:javascript
复制
def delete_row_csr(mat, i):
    if not isinstance(mat, scipy.sparse.csr_matrix):
        raise ValueError("works only for CSR format -- use .tocsr() first")
    n = mat.indptr[i+1] - mat.indptr[i]
    if n > 0:
        mat.data[mat.indptr[i]:-n] = mat.data[mat.indptr[i+1]:]
        mat.data = mat.data[:-n]
        mat.indices[mat.indptr[i]:-n] = mat.indices[mat.indptr[i+1]:]
        mat.indices = mat.indices[:-n]
    mat.indptr[i:-1] = mat.indptr[i+1:]
    mat.indptr[i:] -= n
    mat.indptr = mat.indptr[:-1]
    mat._shape = (mat._shape[0]-1, mat._shape[1])

在LIL格式中,它甚至更简单:

代码语言:javascript
复制
def delete_row_lil(mat, i):
    if not isinstance(mat, scipy.sparse.lil_matrix):
        raise ValueError("works only for LIL format -- use .tolil() first")
    mat.rows = np.delete(mat.rows, i)
    mat.data = np.delete(mat.data, i)
    mat._shape = (mat._shape[0] - 1, mat._shape[1])
票数 26
EN

Stack Overflow用户

发布于 2014-10-22 18:04:36

Pv.的答案是一个好的、可靠的就地解决方案,它需要

代码语言:javascript
复制
a = scipy.sparse.csr_matrix((100,100), dtype=numpy.int8)
%timeit delete_row_csr(a.copy(), 0)
10000 loops, best of 3: 80.3 us per loop

对于任何数组大小。由于布尔索引适用于稀疏矩阵,至少在scipy >= 0.14.0中是这样,所以我建议在删除多行时使用它:

代码语言:javascript
复制
def delete_rows_csr(mat, indices):
    """
    Remove the rows denoted by ``indices`` form the CSR sparse matrix ``mat``.
    """
    if not isinstance(mat, scipy.sparse.csr_matrix):
        raise ValueError("works only for CSR format -- use .tocsr() first")
    indices = list(indices)
    mask = numpy.ones(mat.shape[0], dtype=bool)
    mask[indices] = False
    return mat[mask]

此解决方案删除单行所需的时间要长得多

代码语言:javascript
复制
%timeit delete_rows_csr(a.copy(), [50])
1000 loops, best of 3: 509 us per loop

但是对于删除多行更有效,因为执行时间几乎不会随着行数的增加而增加。

代码语言:javascript
复制
%timeit delete_rows_csr(a.copy(), numpy.random.randint(0, 100, 30))
1000 loops, best of 3: 523 us per loop
票数 13
EN

Stack Overflow用户

发布于 2012-10-26 05:34:13

您可以使用以下命令从CSR矩阵X中删除行0 < i < X.shape[0] - 1

代码语言:javascript
复制
scipy.sparse.vstack([X[:i, :], X[i:, :]])

您可以分别使用X[1:, :]X[:-1, :]删除第一行或最后一行。一次删除多行可能需要使用您自己的函数。

对于CSR以外的其他格式,这可能不一定有效,因为并非所有格式都支持行切片。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13077527

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档