我的目标是非常快速地建立稀疏的CSR矩阵。目前,它是我过程中的主要瓶颈,我已经通过相对快速地构建coo矩阵,然后使用tocsr()对其进行了优化。
但是,我想直接构造csr矩阵必须更快吗?
我有一个非常特殊的稀疏矩阵格式,它也很大(即100000x50000的量级)。我已经在网上查看了其他答案,但大多数都没有解决我的问题。
稀疏矩阵结构:
稀疏矩阵H由大小为N的W个列表组成,或者由大小为NxW的初始数组建立,将其称为A。沿着对角线,大小为N的列表重复N次。因此,对于H的前N行,重复A [:,0],但每行沿N步滑动。
与COO.tocsr()的比较
当我按比例放大N和W并首先建立COO矩阵,然后运行tocsr()时,实际上比直接建立CSR矩阵要快。我不确定为什么会这样吗?我想知道是否可以通过某种方式利用稀疏矩阵H的结构?由于其中存在许多重复元素。
代码示例
这是一个代码示例,用于可视化小样本情况下发生的情况:
from scipy.sparse import linalg, dok_matrix, coo_matrix, csr_matrix
import numpy as np
import matplotlib.pyplot as plt
def test_csr(testdata):
indices = [x for _ in range(W-1) for x in range(N**2)]
ptrs = [N*(i) for i in range(N*(W-1))]
ptrs.append(len(indices))
data = []
# loop along the first axis
for i in range(W-1):
vec = testdata[:,i].squeeze()
# repeat vector N times
for i in range(N):
data.extend(vec)
Hshape = ((N*(W-1), N**2))
H = csr_matrix((data, indices, ptrs), shape=Hshape)
return H
N = 4
W = 8
testdata = np.random.randn(N,W)
print(testdata.shape)
H = test_csr(testdata)
plt.imshow(H.toarray(), cmap='jet')
plt.show()
答案 0 :(得分:0)
看起来您的输出仅具有测试数据的前W-1
行。我不确定这是否是故意的。我的解决方案假定您要使用所有testdata
。
构造COO矩阵时,是否还在以类似方式构造索引和数据?
可能会加快构建csr_matrix
的一件事是使用内置的numpy函数为csr_matrix
生成数据,而不是python循环和数组。我希望这可以显着提高生成索引的速度。您可以根据矩阵的大小将dtype调整为其他类型的int。
N = 4
W = 8
testdata = np.random.randn(N,W)
ptrs = N*np.arange(W*N+1,dtype='int')
indices = np.tile(np.arange(N*N,dtype='int'),W)
data = np.tile(testdata,N).flatten()
Hshape = ((N*W, N**2))
H = csr_matrix((data, indices, ptrs), shape=Hshape)
另一种可能性是首先构造大数组,然后一次定义每个N
垂直列块。这意味着在将原始数据放入稀疏矩阵之前,无需复制大量数据。但是,转换矩阵类型可能会很慢。
N = 4
W = 8
testdata = np.random.randn(N,W)
Hshape = ((N*W, N**2))
H = sp.sparse.lol_matrix(Hshape)
for j in range(N):
H[N*np.arange(W)+j,N*j:N*(j+1)] = testdata.T
H = H.tocsc()