python - np.array arr.itemsize 与 sys.getsizeof(arr[0])

标签 python numpy types numpy-ndarray

给定一个数组

arr = array([  9.93418544e+00,   1.17237323e+01,   1.34554537e+01,
         2.43598467e+01,   2.72818286e+01,   3.11868750e+01,...])

当执行以下命令时,我得到一些输出:

arr.itemsize # 8
type(arr[0]) # numpy.float64
sys.getsizeof(np.float64()) # 32
sys.getsizeof(arr[0]) # 32
arr.dtype # dtype('float64')

itemsize 似乎无法正常工作。我很感兴趣为什么会发生这种情况?

我与

一起工作
print(sys.version)
3.5.5 | packaged by conda-forge | (default, Jul 24 2018, 01:52:17) [MSC v.1900 64 bit (AMD64)]
numpy==1.10.4

最佳答案

It seems that itemsize doesn't work properly.

确实如此,不同的结果是由于 Python 对象与 numpy 中的项目不同而导致的。

在Python中,一切都是对象。数据被“装箱”。这意味着,例如对于 int,我们得到:

>>> sys.getsizeof(2)
28

即 28 个字节。那是很多。在大多数编程语言中,int 占用 2 到 8 个字节。如果是 32 位 int,则需要 4 个字节。

但在Python中,一个对象有很多“上下文”。例如一些字节用来表示对象的类型等。

但是 Numpy 不是在 Python 中实现的,它不是一个使用 Python 对象本身的库。它更像是一个用 C 实现的库,并且具有良好的 Python 接口(interface)。因此,这意味着列表 [1, 4, 2, 5] 在 Python 中不是存储为具有四个对 int 对象的引用的列表,而是存储为数组,通常与“未装箱”的元素。因此,考虑到 int 每个 32 位、4*32 位以及数组周围“上下文”的一些额外空间,上述内容将采用。

因此,元素可以以更节省空间的方式存储。这使得处理值变得更容易,因为我们在这里不跟随指针,而是直接跟随值(有一些方法可以将引用存储在 numpy 数组中,但现在让我们忽略它)。此外,到目前为止,numpy 数组占用的内存比等效的 Python 列表(连同它所包含的项目)要少。

但是,如果您从 numpy 数组中获取一项,则需要为此创建一个 Python 对象。因此,这意味着这里它将构造一个 numpy.float64 对象,其中包含该值,但又包含该值周围的大量“上下文”。这会导致使用更多内存。

numpy 构造特定类型对象的数组这一事实也会产生一些后果。例如,如果您使用 numpy.int16,则意味着无法将大于 32767 的值存储到其中,因为该值无法用 16 位 2-complement 表示形式表示:

>>> np.int16(32767)
32767
>>> np.int16(32768)
-32768

此外,如果不使用 Python 对象引用或其他一些“技巧”,就无法构造一个包含不同类型对象的数组。例如,Numpy 构造一个 int16 数组,这意味着它将 160 位解释为 10 个 16 位数字。在Python中,列表本身包含对对象的引用,并且Python对象知道它是什么类型,因此这意味着我们可以设置对另一种类型的另一个对象的引用。

关于python - np.array arr.itemsize 与 sys.getsizeof(arr[0]),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53141990/

相关文章:

python - mysql和python的编码问题

python - NumPy:使用 'np.save()' 和 'allow_pickle=False' 的后果

java - 如何使用If else语句创建突发报告以进行绩效评估?

python - 类型错误 : Mismatch between array dtype ('object' ) and format specifier ('%.18e' )

python - 将 Numpy 数组转换为稀疏字典的最快方法?

scala - 允许方法签名中存在子类型的特征

c++ - 如何添加/子 int 到 BYTE 类型?

c# - 当前类型是接口(interface),无法构造。您是否缺少类型映射?

python - 使用 Anaconda 克隆根环境

python - 是什么导致了数学域错误?