我使用的是不同精度的numpy浮点数,但是无论我使用什么精度,64、32或16,对象都使用相同的字节数(单个浮点数为48字节)!下面是代码:
import numpy as np
from pympler.asizeof import asizeof
w = np.float32(2)
print(f"{asizeof(w)=}")
w = np.float64(2)
print(f"{asizeof(w)=}")
w = np.float16(2)
print(f"{asizeof(w)=}")
知道为什么会这样吗?
更新:
我在这里使用pympler来检查对象(w)的确切大小,但我也用大量的单个numpy浮点数(每个数字存储为一个字典值(具有不同的键)来测试这个值,通过观察进程中RAM的使用情况,我可以看到,无论我使用何种精度,RAM的使用都不会改变。
发布于 2022-05-16 16:07:02
我不知道pympler
做什么,也不知道它在测量numpy
对象的大小时有多精确。sys.getsizeof
是一个更常见的工具。我怀疑pympler
试图绕过已知的列表和数据集getsizeof
的限制,但对于numpy
来说,这是相当好的。
In [44]: import sys
In [45]: sys.getsizeof(np.float32(2))
Out[45]: 28
In [46]: sys.getsizeof(np.float64(2))
Out[46]: 32
In [47]: sys.getsizeof(np.float16(2))
Out[47]: 26
这些数字表明,这些对象具有24字节的“开销”,16的数据为2字节,32的为2字节,64的为8。
通常,我们不直接创建np.float64
对象。相反,我们使用特定的dtype创建数组,并在索引特定元素时获得类似于np.float64
对象的内容。请记住,numpy
不通过引用存储值(除非它的对象dtype更像list
)。
相反,请查看一个数组:
In [48]: x = np.arange(24)
In [49]: x.dtype
Out[49]: dtype('int64')
In [50]: x.nbytes
Out[50]: 192 # 24 * 8
In [51]: sys.getsizeof(x)
Out[51]: 304
In [52]: 304-192
Out[52]: 112 # array 'overhead'
In [53]: y = np.array([0])
In [54]: y.nbytes
Out[54]: 8
In [55]: sys.getsizeof(y)
Out[55]: 120 # same 112 byte overhead
因此,数组的大小为112个字节加上它的nbytes
,这是我们从dtype
和shape
获得的。这是假设数组“拥有”它的数据,也就是说,它不是其他数组的view
。
In [57]: type(x)
Out[57]: numpy.ndarray
In [58]: type(x[0])
Out[58]: numpy.int64
x
的“提取”元素为int64
类型。x
的数据存储为24*8字节,而不是24 32字节对象。
https://stackoverflow.com/questions/72257722
复制相似问题