用向量中的条目替换 csr_matrix 行中的零个元素

Replace zero elements in rows of a csr_matrix with entries from a vector

我有一个 sparse.csr_matrix M 和一个具有以下维度的向量 V。

M: 0.15M x 1.3M
V: 0.15M

我想用 V 中的相应条目替换 M 行中的所有 0 元素。

M = [[0, 1, 2],
     [3, 4, 0],
     [6, 0, 8]]
V = [[11],
     [22],
     [33]]

我想将 M 修改为 M' 这样

M = [[11,  1,  2],
     [ 3,  4, 22],
     [ 6, 33,  8]]

这可以很容易地在循环中完成,但我想知道是否有更优雅的 Python 方式。由于我的数据量很大,我正在寻找一种非常快速的方法来完成这项任务。

循环版本如下所示:

for i in range(0,3):
    for j in range(0,3):
        if M[i,j] == 0 and V[i] !=0:
            M[i,j] = V[i]

这里有一些应该很快的东西,并且不会使 M 密集。结果虽然会很密集。没有办法解决

V展开为与M大小相同的矩阵

In [711]: Z = np.repeat(V,M.shape[1],axis=1)

In [712]: idx=M.nonzero()   

In [713]: Z[idx]=M.data

In [714]: Z
Out[714]: 
array([[11,  1,  2],
       [ 3,  4, 22],
       [ 6, 33,  8]])

它找到 M 的所有非零值所在的位置(基本上是 M.tocoo()rowcol 属性。然后只需替换 fill Z 中的值与 M.

中对应的 data

如果 M 没有被修剪,这将失败;其中一些元素已设置为零。那是因为 M.nonzero 的完整代码是:

    A = self.tocoo()
    nz_mask = A.data != 0
    return (A.row[nz_mask],A.col[nz_mask])

使用起来可能更安全

In [717]: Mc=M.tocoo()

In [718]: Z[Mc.row, Mc.col] = Mc.data

In [719]: Z
Out[719]: 
array([[11,  1,  2],
       [ 3,  4, 22],
       [ 6, 33,  8]])

当从 csr 转换为 coo 时,这将防止 data 可能重新排序。