首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将列表转换为numpy数组,从而产生比预期大得多的内存。

将列表转换为numpy数组,从而产生比预期大得多的内存。
EN

Stack Overflow用户
提问于 2018-02-11 03:17:54
回答 1查看 1.4K关注 0票数 2

我有一个包含2940个元素的列表-每个元素都是一个(60,2094) numpy数组。

代码语言:javascript
复制
print('DataX:')
print('len:')
print(len(dataX))
print('shape:')
for i in range(5):
    print(dataX[i].shape)
print('dtype:')
print(dataX[0].dtype)

print('size',sys.getsizeof(dataX)/1000000)

在以下方面的成果:

代码语言:javascript
复制
DataX:
len:
2940
shape:
(60, 2094)
(60, 2094)
(60, 2094)
(60, 2094)
(60, 2094)
dtype:
float64
size 0.023728

但是,如果我尝试将其提交给numpy数组(这将导致形状为(2940,60,2094) ),则数组的大小要大得多。

代码语言:javascript
复制
#convert list to array

X = np.array(dataX)
print('X:')
print('shape', X.shape)
print('size',sys.getsizeof(X)/1000000)

输出:

代码语言:javascript
复制
DataX:
shape (2940, 60, 2094)
size 2955.052928

为什么是这种情况?

如果我用一个更大的数据集来尝试,最终会出现“内存”错误。

EN

回答 1

Stack Overflow用户

发布于 2018-02-11 04:13:51

来自sys.getsizeof文档

只计算直接归因于对象的内存消耗,而不是它引用的对象的内存消耗。

sys.getsizeof返回列表对象本身的内存消耗,不包括列表包含的对象。只有一个数组:

代码语言:javascript
复制
In [3]: arr = np.zeros(dtype=np.float64, shape=(60, 2094))

In [4]: arr.size
Out[4]: 125640

In [5]: arr.nbytes
Out[5]: 1005120 

封装基元数组的python对象增加了大约100个字节。

注意,作为对象总是存在开销,请注意:

代码语言:javascript
复制
In [6]: sys.getsizeof(arr)
Out[6]: 1005232

那么,实际的内存消耗是关于:

代码语言:javascript
复制
In [7]: arr.nbytes*1e-9
Out[7]: 0.00100512 # one megabyte

如果我们有2940个这样的物体,那就是:

代码语言:javascript
复制
In [8]: arr.nbytes*2940*1e-9
Out[8]: 2.9550528000000003 # almost 3 gigabytes

如果我真的把这些都列在一个清单里:

代码语言:javascript
复制
In [13]: alist = []

In [14]: alist.append(arr)

In [15]: for _ in range(2940 - 1):
    ...:     alist.append(arr.copy())
    ...:

列表对象本身本质上是由一个py_object指针数组支持的。在我的机器(64位)上,指针将是一个机器字,即64位或8字节。所以:

代码语言:javascript
复制
In [19]: sys.getsizeof(alist)
Out[19]: 23728

In [20]: 8*len(alist) # 8 bytes per pointer
Out[20]: 23520

因此,sys.getsizeof只计算一个指针数组,加上对象开销,但这甚至与所指向的数组对象所消耗的3G字节的计算值相差甚远。

瞧,瞧:

代码语言:javascript
复制
In [21]: arr = np.array(alist)

In [22]: arr.shape
Out[22]: (2940, 60, 2094)

In [23]: arr.size
Out[23]: 369381600

In [24]: arr.nbytes
Out[24]: 2955052800

In [25]: arr.nbytes* 1e-9
Out[25]: 2.9550528000000003
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48727939

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档