我有一个相当大的稀疏矩阵 A
作为 scipy.sparse.csr_matrix .它具有以下属性:
A.shape: (77169, 77169)
A.nnz: 284811011
A.dtype: dtype('float16')
现在我必须使用 .toarray()
将其转换为密集数组。我对内存使用量的估计是
77169**2 * (16./8.) / 1024.**3 = 11.09... GB
这很好,因为我的机器有大约 48GB 的内存。事实上,如果我创建 a=np.ones((77169, 77169), dtype=np.float16)
效果很好并且确实 a.nbytes/1024.**3 = 11.09 ...
。但是,当我在稀疏矩阵上运行 A.toarray()
时,它会打包所有内存并在某个时候开始使用交换(它不会引发 MemoryError
).这里出了什么问题?它不应该很容易融入我的内存吗?
最佳答案
对于 csr
toarray()
做
self.tocoo(copy=False).toarray(order=order, out=out)
您可以继续跟踪 coo.toarray
,但我怀疑它最终使用的是编译代码。但我怀疑它最终会做相当于:
In [715]: M=sparse.random(10,10,.2,format='csr')
In [717]: M=M.astype(np.float16)
In [718]: A = np.zeros(M.shape, M.dtype)
In [719]: Mo=M.tocoo()
In [720]: A[Mo.row, Mo.col] = Mo.data
奇怪的是如果我这样做
In [728]: Mo.toarray()
...
257 coo_todense(M, N, self.nnz, self.row, self.col, self.data,
--> 258 B.ravel('A'), fortran)
259 return B
...
ValueError: Output dtype not compatible with inputs.
float16
有问题。 Mo.astype(float).toarray()
工作正常。即使将 toarray(out=out)
与 float16 一起使用,我也会收到此错误,这让我怀疑 coo_todense
仅使用几个 dtype 选项进行编译。也许我稍后会深入研究。
In [741]: scipy.__version__
Out[741]: '0.18.1'
Warren 错误报告中的评论
but the xxx_todense functions are actually A += X,
表明从 Mo.data
到 A[]
的复制比指示的更复杂。 toarray
对重复项求和,就像使用 Mo.tocsr()
或 Mo.sum_duplicates()
一样。
关于python - scipy.sparse.csr_matrix.toarray() 的大量内存使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44003497/