繁体   English   中英

numpy float64、float32 和 float16 标量都使用相同的字节数

[英]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 ,我们从dtypeshape得到。 这是假设数组“拥有”它的数据,也就是说,它不是其他数组的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM