为什么空的Python列表比空的NumPy数组消耗更少的内存?

roqulrg3  于 2023-08-05  发布在  Python
关注(0)|答案(1)|浏览(99)

我认为NumPy数组总是比Python列表消耗更少的内存。然而,当我用一个空列表测试时,纯Python列表有56个字节,NumPy数组的大小是112个字节。为什么?为什么?


的数据

yvt65v4c

yvt65v4c1#

我重新打开它,因为副本集中在np.reshape如何产生view并改变getsizeof看到的内容。这里的问题是列表与数组的大小。
让我举例说明:(张贴此代码的图像是不好的SO风格。我们更喜欢复制粘贴代码)
您的列表和数组:

In [458]: alist = [1,2,3,4,5,7,'a','b','c','@']
In [459]: alist
Out[459]: [1, 2, 3, 4, 5, 7, 'a', 'b', 'c', '@']
In [460]: arr = np.array(alist)
In [461]: arr
Out[461]: array(['1', '2', '3', '4', '5', '7', 'a', 'b', 'c', '@'], dtype='<U21')

字符串
注意dtype。数组包含字符串,而不是数字。

In [462]: arr.nbytes
Out[462]: 840
In [463]: import sys
In [464]: sys.getsizeof(arr)
Out[464]: 952


getsizeof得到840,加上112“开销”。对于常规数组,getsizeof给出了一个合理的数字,但实际上并不需要。
但对于列表:

In [465]: sys.getsizeof(alist)
Out[465]: 136


我们可以通过检查长度和dtype来获得840字节:

In [466]: len(arr)
Out[466]: 10
In [467]: 4*21*10
Out[467]: 840


对于列表,“开销”是56,其余的是指针的存储-其中10个。

In [468]: sys.getsizeof([])
Out[468]: 56
In [469]: 56+80
Out[469]: 136


列表也可以有“增长空间”的内存。getsizeof不测量指向的对象所使用的内存。在这种情况下,小整数已经存在,不需要任何额外的内存。每个字符串占用额外的50字节。列表可以存储各种类型的对象,包括其他列表和字典和数组等。getsizeof没有告诉我们这些。
可以为数组指定不同的dtype,从而减少内存:

In [470]: arr1 = np.array(alist,'U1')
In [471]: arr1
Out[471]: array(['1', '2', '3', '4', '5', '7', 'a', 'b', 'c', '@'], dtype='<U1')
In [472]: arr1.nbytes
Out[472]: 40
In [473]: sys.getsizeof(arr1)
Out[473]: 152


总而言之,要从getsizeof中获得任何有用的东西,您必须了解对象/类是如何存储的,以及该函数度量的是什么。对于python初学者来说,这两个主题都不是一个微不足道的主题。好吧,初学者应该学习,很快,如果不是以后,如何存储列表和数组。

相关问题