python – 将符合特定条件的scipy.sparse矩阵行设置为零

前端之家收集整理的这篇文章主要介绍了python – 将符合特定条件的scipy.sparse矩阵行设置为零前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我想知道用稀疏矩阵替换不满足某个条件的行的最佳方法是什么.例如(我使用普通数组进行说明):

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

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

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

  1. array([[0,[0,2]])
  2. @H_301_9@

这对于密集矩阵来说非常简单:

  1. row_sum = a.sum(axis=1)
  2. to_keep = row_sum >= 10
  3. a[to_keep] = np.zeros(a.shape[1])
  4. @H_301_9@

但是,当我尝试:

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

我收到此错误

  1. raise NotImplementedError("Fancy indexing in assignment not "
  2. NotImplementedError: Fancy indexing in assignment not supported for csr matrices.
  3. @H_301_9@

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

  1. def zero_out_unfit_rows(s_mat,limit_row_sum):
  2. row_sum = s_mat.sum(axis=1).T.A[0]
  3. to_keep = row_sum <= limit_row_sum
  4. to_keep = to_keep.astype('int8')
  5. temp_diag = get_sparse_diag_mat(to_keep)
  6. return temp_diag * s_mat
  7. def get_sparse_diag_mat(my_diag):
  8. N = len(my_diag)
  9. my_diags = my_diag[np.newaxis,:]
  10. return sparse.dia_matrix((my_diags,[0]),shape=(N,N))
  11. @H_301_9@

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

但是,我觉得有更好的,更多的scipynic解决方案.有更好的解决方案吗?

最佳答案
不确定它是否非常scithonic,但是通过直接访问guts可以更好地完成稀疏矩阵上的大量操作.对于你的情况,我个人会这样做:

  1. a = np.array([[0,2]])
  2. sps_a = sps.csr_matrix(a)
  3. # get sum of each row:
  4. row_sum = np.add.reduceat(sps_a.data,sps_a.indptr[:-1])
  5. # set values to zero
  6. row_mask = row_sum > 10
  7. nnz_per_row = np.diff(sps_a.indptr)
  8. sps_a.data[np.repeat(row_mask,nnz_per_row)] = 0
  9. # ask scipy.sparse to remove the zeroed entries
  10. sps_a.eliminate_zeros()
  11. >>> sps_a.toarray()
  12. array([[0,2]])
  13. >>> sps_a.nnz # it does remove the entries,not simply set them to zero
  14. 10
  15. @H_301_9@

猜你在找的Python相关文章