Scipy稀疏矩阵中的行分割

3

我希望能够将稀疏矩阵的行通过数组中的标量进行划分。

例如,我有一个 csr_matrix C

C = [[2,4,6], [5,10,15]]
D = [2,5]

我希望在除法后得到 C 的结果为:
result = [[1, 2, 3], [1, 2, 3]]

我已经尝试使用我们用于numpy数组的方法:

result = C / D[:,None]

但这种方法似乎非常缓慢。如何在稀疏矩阵中高效地实现呢?

之前关于按行除的问题,请参见:https://stackoverflow.com/questions/44080315/division-of-sparse-matrix - hpaulj
4个回答

8

方法 #1

这里有一个使用手动复制和索引的稀疏矩阵解决方案 -

from scipy.sparse import csr_matrix

r,c = C.nonzero()
rD_sp = csr_matrix(((1.0/D)[r], (r,c)), shape=(C.shape))
out = C.multiply(rD_sp)

与使用C / D [:, None]创建完整矩阵的输出不同,此方法的输出也是一个稀疏矩阵。因此,该方法可以节省内存。

通过使用np.repeat进行复制而不是索引可能会提高性能 -

val = np.repeat(1.0/D, C.getnnz(axis=1))
rD_sp = csr_matrix((val, (r,c)), shape=(C.shape))

方法二

另一种方法可以涉及到稀疏矩阵的data方法,它为我们提供了一个扁平化的视图,以便在原地得到结果,并且避免使用nonzero,如下所示 -

val = np.repeat(D, C.getnnz(axis=1))
C.data /= val

1
太棒了!它像魔法一样奏效了!在我的数据集上,我的方法需要60秒的时间。现在只需要1秒钟了。谢谢。 - user3787291
@user3787291 第二种方法怎么样? - Divakar
1
是的,它也起作用了。如果我需要按列进行划分怎么办?你如何按列进行划分? - user3787291
@user3787291 我遇到了这个问题,但必须按列进行解决。只需要做一个小修改。 (1.0/D)[r] 改为 (1.0/D)[c]rD_sp = csr_matrix(((1.0/D)[c], (r,c)), shape=(C.shape)) - Bhavul

0
问题:我想通过给定的数组将稀疏矩阵的行除以标量。 例如: C = [[2,4,6], [5,10,15]] D = [2,5]
答案:使用稀疏矩阵接口提供的"multiply" - 它允许按点乘矩阵和向量以及标量。
    C = [[2,4,6], [5,10,15]]
    D = [2,5]

from scipy.sparse import csr_matrix

c = csr_matrix(C) c2 = c.multiply( 1/np.array(D).reshape(2,1) ) c2.toarray() '输出结果:' array([[ 2, 4, 6], [ 5, 10, 15]], dtype=int64)

-1
如果您首先将D转换为numpy.matrix类型(我假设您可以这样做,除非D太大而无法放入内存),那么您只需运行
C.multiply(1.0 / D.T)

得到你想要的。


-1

一行代码:result = [[C[i][j]/D[i] for j in range(len(C[0]))] for i in range(len(D))]

C = [[2,4,6], [5,10,15]] #len(C[0]) = 3
D = [2,5] # len(D) = 2
result = [[C[i][j]/D[i] for j in range(len(C[0]))] for i in range(len(D))]
print result

我没有看到这个按要求针对csr_matrix起作用。 - ldmtwo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接