[英]How many digits can float8, float16, float32, float64, and float128 contain?
[英]numpy float64, float32, and float16 scalars all use the same number of bytes
我正在使用具有不同精度的 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)=}")
知道为什么会这样吗?
更新:
我在这里使用 pymler 来检查对象 (w) 的确切大小,但我也用大量的单个 numpy 浮点数对此进行了测试,每个浮点数都存储为字典值(使用不同的键),我可以通过目测进程的 RAM 使用率,无论我使用什么精度,RAM 使用率都不会改变。
我不知道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 字节的“开销”,其中 2 个字节用于 16 的数据,另外两个用于 32,而 8 用于 64。
通常我们不会直接创建np.float64
对象。 相反,我们创建一个具有特定 dtype 的数组,并在索引特定元素时获得类似np.float64
对象的东西。 请记住, numpy
不会通过引用存储值(除非它是 object 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 字节的对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.