我有两个相同维度的大型稀疏矩阵,其中一个具有哑元(0/1),我需要计算它们的Hadamard乘积(按元素相乘):
density = 40000000
rows = 1500000
cols = 1000
a = sparse.csr_matrix(sparse.coo_matrix((np.random.random_sample((density,)),
(np.random.choice(np.arange(rows), density),
np.random.choice(np.arange(cols), density))),
shape=(rows,cols)))
b = sparse.csr_matrix(sparse.coo_matrix((np.random.choice(np.arange(2), density),
(np.random.choice(np.arange(rows), density),
np.random.choice(np.arange(cols), density))),
shape=(rows,cols)))
由于这是重复几千次的一系列矩阵运算中唯一的耗时步骤(在我的机器上,此乘法大约需要1.7秒),因此我正在研究如何使这一步骤更有效
与乘法相反。
a.multiply(b)
..我在想,因为第二个矩阵是一个伪矩阵,所以真正需要发生的是获取伪矩阵的非零索引,然后用这些坐标保留另一个矩阵的值。下面的简化示例只是为了说明这一点。
array([[0.94510061, 0.10967919, 0.29398388], array([[0., 0., 1.], array([[0., 0., 0.29398388],
[0.94510061, 0.10967919, 0.29398388], [0., 0., 1.], [0., 0., 0.29398388],
[0.94510061, 0.10967919, 0.29398388], x [0., 1., 0.], = [0., 0.10967919, 0.],
[0.41112772, 0.94716107, 0.2308533 ], [1., 0., 0.], [0.41112772, 0., 0.],
[0.41112772, 0.94716107, 0.2308533 ]]) [0., 1., 0.]]) [0., 0.94716107, 0.]])
要实现此目的,我将矩阵a
切片如下所示,结果证明这非常耗时(计划是将vals
放在新的coo_matrix具有相同的坐标)。
nz = sparse.csr_matrix.nonzero(b)
vals = a[nz[0], nz[1]]
问题1:是否有更有效的方法来分割稀疏矩阵?
我知道密集a
(a.A[nz[0], nz[1]]
)的切片速度很多,但是将其转换为密集的开销却超出了我试图实现的目的实现。
此外,我读了另一个SO问题,试图达到相反的效果(即稀疏矩阵的有效切片),最好的方法可能是与虚拟对象相乘-这对我的问题不是很令人鼓舞。所以, 第二季度,如果有人能想到比我尝试实现的解决方案更好的解决方案,那将是非常受欢迎的。