python - 将满足特定条件的 scipy.sparse 矩阵的行设置为零

标签 python numpy scipy sparse-matrix

我想知道将不满足特定条件的行替换为稀疏矩阵的零的最佳方法是什么。例如(我使用普通数组来说明):

我想用一行零替换总和大于 10 的每一行

a = np.array([[0,0,0,1,1],
              [1,2,0,0,0],
              [6,7,4,1,0],  # sum > 10
              [0,1,1,0,1],
              [7,3,2,2,8],  # sum > 10 
              [0,1,0,1,2]])

我想用零替换 a[2] 和 a[4],所以我的输出应该如下所示:

array([[0, 0, 0, 1, 1],
       [1, 2, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 1, 1, 0, 1],
       [0, 0, 0, 0, 0],
       [0, 1, 0, 1, 2]])

这对于稠密矩阵来说相当简单:

row_sum = a.sum(axis=1)
to_keep = row_sum >= 10   
a[to_keep] = np.zeros(a.shape[1]) 

但是,当我尝试时:

s = sparse.csr_matrix(a) 
s[to_keep, :] = np.zeros(a.shape[1])

我收到这个错误:

    raise NotImplementedError("Fancy indexing in assignment not "
NotImplementedError: Fancy indexing in assignment not supported for csr matrices.

因此,我需要一个不同的稀疏矩阵解决方案。我想到了这个:

def zero_out_unfit_rows(s_mat, limit_row_sum):
    row_sum = s_mat.sum(axis=1).T.A[0]
    to_keep = row_sum <= limit_row_sum
    to_keep = to_keep.astype('int8')
    temp_diag = get_sparse_diag_mat(to_keep)
    return temp_diag * s_mat

def get_sparse_diag_mat(my_diag):
    N = len(my_diag)
    my_diags = my_diag[np.newaxis, :]
    return sparse.dia_matrix((my_diags, [0]), shape=(N,N))

这依赖于这样一个事实,即如果我们将单位矩阵中对角线的第 2 和第 4 个元素设置为零,则预乘矩阵的行将设置为零。

但是,我觉得有一个更好、更科学的解决方案。有更好的解决方案吗?

最佳答案

不确定它是否非常scithonic,但很多稀疏矩阵上的操作最好通过直接访问内脏来完成。对于您的情况,我个人会这样做:

a = np.array([[0,0,0,1,1],
              [1,2,0,0,0],
              [6,7,4,1,0],  # sum > 10
              [0,1,1,0,1],
              [7,3,2,2,8],  # sum > 10 
              [0,1,0,1,2]])
sps_a = sps.csr_matrix(a)

# get sum of each row:
row_sum = np.add.reduceat(sps_a.data, sps_a.indptr[:-1])

# set values to zero
row_mask = row_sum > 10
nnz_per_row = np.diff(sps_a.indptr)
sps_a.data[np.repeat(row_mask, nnz_per_row)] = 0
# ask scipy.sparse to remove the zeroed entries
sps_a.eliminate_zeros()

>>> sps_a.toarray()
array([[0, 0, 0, 1, 1],
       [1, 2, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 1, 1, 0, 1],
       [0, 0, 0, 0, 0],
       [0, 1, 0, 1, 2]])
>>> sps_a.nnz # it does remove the entries, not simply set them to zero
10

关于python - 将满足特定条件的 scipy.sparse 矩阵的行设置为零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19034163/

相关文章:

python - 使用 python + 元数据读写立体声 .wav 文件

python - Pyspark - 获取具有条件的列的累计总和

python - 如何定义可为空的响应属性?

python - 将 csv 读入 Python 时跳过相同的值

python - NumPy 和 python

python - 在python中求解非线性方程

python - 我可以在 Python 2.7 中编写一个执行符号计算的函数吗?

python - 如何在 Linux 下 ssh.invoke_shell() 工作

python - 将直方图箱分配给每个数据点

python - numpy数组的插值最大插值距离