假设我有一个二维矩阵作为numpy数组。如果我想删除这个矩阵中具有特定索引的行,我会使用numpy.delete()
。下面是我的意思的一个例子:
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数组来做到这一点,但我不想这样做。有没有其他方法可以做到这点?
非常感谢!
发布于 2012-10-26 07:21:58
对于CSR来说,这可能是最有效的方式:
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格式中,它甚至更简单:
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])
发布于 2014-10-22 18:04:36
Pv.的答案是一个好的、可靠的就地解决方案,它需要
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
中是这样,所以我建议在删除多行时使用它:
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]
此解决方案删除单行所需的时间要长得多
%timeit delete_rows_csr(a.copy(), [50])
1000 loops, best of 3: 509 us per loop
但是对于删除多行更有效,因为执行时间几乎不会随着行数的增加而增加。
%timeit delete_rows_csr(a.copy(), numpy.random.randint(0, 100, 30))
1000 loops, best of 3: 523 us per loop
发布于 2012-10-26 05:34:13
您可以使用以下命令从CSR矩阵X
中删除行0 < i < X.shape[0] - 1
scipy.sparse.vstack([X[:i, :], X[i:, :]])
您可以分别使用X[1:, :]
或X[:-1, :]
删除第一行或最后一行。一次删除多行可能需要使用您自己的函数。
对于CSR以外的其他格式,这可能不一定有效,因为并非所有格式都支持行切片。
https://stackoverflow.com/questions/13077527
复制相似问题