[英]converting a list to numpy array resulting much larger memory than expected
我有一個包含 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
為什么會這樣?
如果我嘗試使用更大的數據集,最終會出現“內存”錯誤。
只考慮直接歸因於對象的內存消耗,而不是它所引用的對象的內存消耗。
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())
...:
列表對象本身基本上由 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 GB。
瞧:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.