簡體   English   中英

列表和 NumPy 數組 memory 大小之間的區別

[英]Difference between list and NumPy array memory size

我聽說 Numpy arrays 比 python 內置列表更有效,而且它們在 ZCD69B4957F06CD8DE219D7 中占用的空間更少。 據我了解,Numpy 將這些對象彼此相鄰地存儲在 memory 中,而列表的 python 實現存儲指向給定值的 8 個字節指針。 但是,當我嘗試在 jupyter notebook 中進行測試時,結果發現兩個對象的大小相同。

import numpy as np
from sys import getsizeof
array = np.array([_ for _ in range(4)])
getsizeof(array), array

返回(128, array([0, 1, 2, 3]))同:

l = list([_ for _ in range(4)])
getsizeof(l), l

給出(128, [0, 1, 2, 3])

你能提供任何明確的例子來說明我如何在 jupyter notebook 中展示它嗎?

getsizeof不能很好地衡量 memory 的使用,尤其是列表。 正如您所注意到的,該列表具有指向 memory 中其他地方的對象的指針緩沖區。 getsizeof記錄緩沖區的大小,但沒有告訴我們有關對象的任何信息。

In [66]: list(range(4))
Out[66]: [0, 1, 2, 3]

該列表有其基本的 object 存儲,加上帶有 4 個指針的緩沖區(加上一些增長空間)。 這些數字存儲在其他地方。 在這種情況下,數字很小,並且已經由解釋器創建和緩存。 所以他們的存儲不會增加任何東西。 但是每次使用都會創建更大的數字(和浮點數),並占用空間。 列表也可以包含任何內容,例如指向其他列表的指針、字符串或字典,或任何其他內容。

In [67]: arr = np.array([i for i in range(4)])   # via list
In [68]: arr
Out[68]: array([0, 1, 2, 3])
In [69]: np.array(range(4))            # more direct
Out[69]: array([0, 1, 2, 3])
In [70]: np.arange(4)
Out[70]: array([0, 1, 2, 3])           # faster

arr也有一個基本的 object 存儲,具有形狀和 dtype 等屬性。 它也有一個數據緩沖區,但是對於像這樣的數字 dtype,該緩沖區具有實際數值(8 字節整數),而不是指向 Python integer 對象的指針。

In [71]: arr.nbytes
Out[71]: 32

該數據緩沖區僅占用 32 個字節 - 4*8。

對於這個小例子, getsizeof返回相同的東西並不奇怪。 基本的 object 存儲比存儲 4 個值的位置更重要。 當使用 1000 個值和多維 arrays 時,memory 的使用明顯不同。

但更重要的是計算速度。 使用數組,您可以執行arr+1arr.sum()類的操作。 它們在編譯后的代碼中運行,並且速度非常快。 類似的列表操作必須以較慢的 Python 速度進行迭代,盡管指針、獲取值等。但是在 arrays 上進行相同類型的迭代甚至更慢。

作為一般規則,如果您從列表開始,並執行append和列表推導等列表操作,最好堅持使用它們。

但是,如果您可以創建一次 arrays,或者從其他 arrays,然后使用numpy方法,您將獲得 10 倍的速度提升。 Arrays 確實更快,但前提是您以正確的方式使用它們。 它們不是列表的簡單替代品。

NumPy 數組具有關於數組 object header 的一般數組信息(如形狀、數據類型等)。 所有值都存儲在 memory 的連續塊中。 但是列表為每個新的 object 分配新的 memory 塊並存儲它們的指針。 因此,當您迭代時,您不會直接在 memory 上進行迭代。 您正在迭代指針。 因此,當您處理大數據時,它並不方便。 這是一個例子:

import sys
import numpy as np

random_values_numpy=np.arange(1000)
random_values=range(1000)  
#Numpy
print(random_values_numpy.itemsize)
print(random_values_numpy.size*random_values_numpy.itemsize)  
#PyList
print(sys.getsizeof(random_values))
print(sys.getsizeof(random_values)*len(random_values))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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