为什么稀疏 csc 矩阵中的每个元素都是 8 个字节?



例如,如果我最初有一个密集矩阵:

A = numpy.array([[0, 0],[0, 1]])

然后使用 csc_matrix(A) 将其转换为 CSC 稀疏矩阵。然后将矩阵存储为:

(1, 1)    1
#(row, column)   val

它由三个值组成。为什么稀疏矩阵的大小只有 8 个字节,即使计算机基本上存储了 3 个值?当然,矩阵的大小至少为 12 个字节,因为整数通常包含 4 个字节。

我不同意稀疏矩阵的大小为 8 个字节。我可能错过了一些东西,但如果我这样做,我会得到一个非常不同的答案:

>>> import sys
>>> import numpy
>>> from scipy import sparse
>>> A = numpy.array([[0, 0],[0, 1]])
>>> s = sparse.csc_matrix(A)
>>> s
<2x2 sparse matrix of type '<class 'numpy.int32'>'
with 1 stored elements in Compressed Sparse Column format>
>>> sys.getsizeof(s)
56

这是内存中数据结构的大小,我向您保证它是准确的。Python必须知道它有多大,因为它会进行内存分配。

另一方面,如果您使用s.data.nbytes

>>> s.data.nbytes       
4

这给出了预期的答案 4。这是意料之中的,因为s报告自身具有一个类型为int32的存储元素。根据文档返回的值,

不包括数组对象的非元素属性消耗的内存。

正如35421869明确指出的那样,这不是一个更准确的结果,只是对不同问题的答案。

我无法解释为什么当结果 8 明显正确时报告值 4 字节。一种可能性是numpy.array([[0, 0],[0, 1]])实际上并不是实际转换为稀疏数组的内容。值 5 从何而来?值 8 与起始值numpy.array([[0, 0],[0, 5.0]])一致。

您的 12 字节数字基于两个未满足的期望。

  1. 可以将稀疏矩阵表示为三元组(行、列、值)的列表。事实上,这就是COO矩阵的存储方式,至少在原则上是这样。但是 CSC 代表压缩稀疏列,因此显式列索引比 COO 矩阵中的索引少。这篇维基百科文章清晰地解释了存储的实际工作原理。
  2. nbytes不报告存储矩阵元素的总内存成本。它报告了一个numpy不变的(在许多不同类型的矩阵上)x.nbytes == np.prod(x.shape) * x.itemsize。这是一个重要的数量,因为矩阵的显式存储元素构成了其最大的附属数据结构,并且必须在连续内存中分配。

相关内容

最新更新