将Scipy稀疏行矩阵添加到另一个稀疏矩阵中。

4
我有一个形状为 (70000, 80000)csr_matrix A 和另一个形状为 (1, 80000)csr_matrix B。如何高效地将B添加到A的每一行?一个想法是创建一个稀疏矩阵 B',其中重复了B的行,但是 numpy.repeat 不起作用,使用一个全是1的矩阵来创建 B' 将非常浪费内存。
我还尝试了遍历每一行的 A 并将其加上 B,但这同样非常耗时。
更新: 我尝试了一些非常简单的方法,似乎比我之前提到的方法更有效率。这个想法是使用 scipy.sparse.vstack
C = sparse.vstack([B for x in range(A.shape[0])])
A + C

这对我的任务表现良好!还有一些发现:我最初尝试了一种迭代方法,其中我多次调用vstack,但这种方法比只调用一次要慢。

1个回答

3

A + B[np.zeros(A.shape[0])] 是另一种将 B 扩展到与 A 相同形状的方法。

它与 Warren Weckesser 的解决方案 比较,具有相似的性能和内存占用。

import numpy as np
import scipy.sparse as sparse

N, M = 70000, 80000
A = sparse.rand(N, M, density=0.001).tocsr()
B = sparse.rand(1, M, density=0.001).tocsr()

In [185]: %timeit u = sparse.csr_matrix(np.ones((A.shape[0], 1), dtype=B.dtype)); Bp = u * B; A + Bp
1 loops, best of 3: 284 ms per loop

In [186]: %timeit A + B[np.zeros(A.shape[0])]
1 loops, best of 3: 280 ms per loop

而且似乎比使用 sparse.vstack 更快:

In [187]: %timeit A + sparse.vstack([B for x in range(A.shape[0])])
1 loops, best of 3: 606 ms per loop

这比我的更简洁;+1。 - Warren Weckesser
事实上,这使我的回答无效了。噗!它消失了。 - Warren Weckesser
@unubtu,你在使用什么样的shell/解释器?那个打印出"In [185]"的东西? - Bob
我发现(玩了很久之后)sparse.bsr_matrix((np.tile(B.data(N,1)).T[:,:,None], B.indices, B.indptr), shape=(N,M)) 可以快速创建正确的 bsr 格式矩阵。但是,应用 tocsr 以便进行加法运算会使总时间与你的答案相同。 - hpaulj

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