簡體   English   中英

將列表轉換為 numpy 數組導致比預期大得多的內存

[英]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 文檔

只考慮直接歸因於對象的內存消耗,而不是它所引用的對象的內存消耗。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM