scipy.sparse.coo_matrix 上的逐元素运算(例如取模)?

Element-wise operations on scipy.sparse.coo_matrix (e.g. modulo)?

如何对 scipy.sparse.coo_matrix 执行逐元素运算(例如取模)?

我是否必须从中创建一个 NumPy 密集数组?如果那样的话,我不会失去创建稀疏矩阵所获得的所有好处吗?

令人惊讶的是,不只是 sparse_input % whatever。那是不支持的。相反,对于标量 RHS,您可以直接操作 COO 格式:

coo_lhs = whatever
scalar_rhs = whatever
coo_result = scipy.sparse.coo_matrix(
    (coo_lhs.data % scalar_rhs, (coo_lhs.row.copy(), coo_lhs.col.copy())),
    shape=coo_lhs.shape)

将稀疏矩阵作为模运算的 RHS 没有意义 - 如果您确定需要,请转换为密集矩阵。

只要element-wise操作不改变数据的稀疏性,就可以使用.data属性,例如:

import scipy as sp
import scipy.sparse


m = (sp.sparse.rand(5, 10, 0.2) * 100).astype(int)
print(m)
  (1, 0)        34
  (1, 2)        2
  (2, 2)        39
  (1, 4)        54
  (3, 4)        22
  (4, 4)        46
  (1, 6)        40
  (1, 7)        97
  (4, 8)        60
  (4, 9)        97
m.data %= 10
print(m)
  (1, 0)        4
  (1, 2)        2
  (2, 2)        9
  (1, 4)        4
  (3, 4)        2
  (4, 4)        6
  (1, 6)        0
  (1, 7)        7
  (4, 8)        0
  (4, 9)        7

这应该是高效的并且不应该有任何转换开销。

请注意,对于零 0absorbing element 的任何运算都可以这样做,至少在非对称(交换)运算的一侧(左侧或右侧)。

例如,在模%运算中,0是左吸收元素,因为0 % a = 0对任何a。整数除法//、除法/(只要不需要区分0.0-0.0)和求幂**(对于正数)也是如此).对于乘法*0是吸收元素。

对于按元素乘法的情况,*/(至少通过标量)由 scipy.sparse.coo_matrix 对象的常规语法支持。