我有一个包含2940个元素的列表 - 每个元素都是一个(60,2094)numpy数组。
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)
结果:
DataX:
len:
2940
shape:
(60, 2094)
(60, 2094)
(60, 2094)
(60, 2094)
(60, 2094)
dtype:
float64
size 0.023728
但是,如果我尝试将其转换为numpy数组(其形状应为(2940,60,2094)),则数组的大小会大得多。
#convert list to array
X = np.array(dataX)
print('X:')
print('shape', X.shape)
print('size',sys.getsizeof(X)/1000000)
输出:
DataX:
shape (2940, 60, 2094)
size 2955.052928
为什么会这样?
如果我尝试使用更大的数据集,我最终会遇到“内存”错误。
答案 0 :(得分:1)
只有直接归因于对象的内存消耗才是 占了,而不是它所指对象的内存消耗。
sys.getsizeof
返回列表对象本身的内存消耗,不包括列表中包含的对象。您的一个阵列:
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个字节。
注意,作为对象的总是开销,请注意:
In [6]: sys.getsizeof(arr)
Out[6]: 1005232
实际内存消耗大约是:
In [7]: arr.nbytes*1e-9
Out[7]: 0.00100512 # one megabyte
如果我们有2940个,那么这些对象就是:
In [8]: arr.nbytes*2940*1e-9
Out[8]: 2.9550528000000003 # almost 3 gigabytes
如果我真的将这些全部放在一个列表中:
In [13]: alist = []
In [14]: alist.append(arr)
In [15]: for _ in range(2940 - 1):
...: alist.append(arr.copy())
...:
list对象本身基本上由py_object指针数组支持。在我的机器(64位)上,指针将是一个机器字,即64位或8字节。所以:
In [19]: sys.getsizeof(alist)
Out[19]: 23728
In [20]: 8*len(alist) # 8 bytes per pointer
Out[20]: 23520
所以sys.getsizeof
只考虑一个指针数组,加上对象开销,但是,即使关闭也不能解释数组对象消耗的3千兆字节数。指着。
瞧瞧:
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