程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python 玩轉數據 6 - NumPy ndarray 數組 和 Python list 列表的區別

編輯:Python

引言

前兩篇文章有介紹 Python 動態類型 共享引用,賦值和拷貝的原理,對 Python list 列表應該有一個深刻的了解。那麼 NumPy 中的 ndarray 數組和 list 列表有啥區別呢。更多 Python 進階系列文章,請參考 Python 進階學習 玩轉數據系列

內容提要:

  1. Python 中不同類型的內存需求
  2. NumPy ndarray Vs. Python list 內存需求
  3. NumPy ndarray Vs. Python list 結構
  4. NumPy ndarray Vs. Python list 計算
  5. NumPy subarray Vs. Python sublist
  6. NumPy ndarray Vs. Python list 總結

Python 中不同類型的內存需求

一個變量被賦值成不同類型的值,它在內存中的存儲需求也是不一樣的。如下:

from sys import getsizeof as byte_size
x = 5
print("byte size of int_type:{}".format(byte_size(x)))
x = 'hello'
print("byte size of str_type:{}".format(byte_size(x)))
x = True
print("byte size of bool_type:{}".format(byte_size(x)))
x = 5.0
print("byte size of float_type:{}".format(byte_size(x)))

輸出:

byte size of int_type:28
byte size of str_type:54
byte size of bool_type:28
byte size of float_type:24

list 中每個元素所占用內存大小取決於每個元素的類型,如下:

from sys import getsizeof as byte_size
list_object = ['Five', 5, 5.0, True]
print("byte size of list_object:{}".format(byte_size(list_object)))
print("byte size of each list item in list_object:{}".format([byte_size(item) for item in list_object]))
print("total byte size of list items in list_object:{}".format(sum([byte_size(item) for item in list_object])))

輸出:

byte size of list_object:96
byte size of each list item in list_object:[53, 28, 24, 28]
byte total size of list items in list_object:133

NumPy ndarray Vs. Python list 內存的需求

先通過代碼來了解一下:

from sys import getsizeof as byte_size
import numpy as np
list_object = [1,2,3,4,5,6]
np_array = np.array(list_object, dtype='int16')
print("list_object:{}".format(list_object))
print("byte size of list_object:{}".format(byte_size(list_object)))
print("byte size of each list item in list_object:{}".format([byte_size(item) for item in list_object]))
print("total byte size of list items in list_object:{}\n".format(sum([byte_size(item) for item in list_object])))
print("np_array:{}".format(np_array))
print("byte size of each item in np_array:{}".format([item.nbytes for item in np_array]))
print("total byte size of items in np_array:{}".format(np_array.nbytes))

輸出:
可見 NumPy array 數組所需內存更少

list_object:[1, 2, 3, 4, 5, 6]
byte size of list_object:112
byte size of each list item in list_object:[28, 28, 28, 28, 28, 28]
total byte size of list items in list_object:168
np_array:[1 2 3 4 5 6]
byte size of each item in np_array:[2, 2, 2, 2, 2, 2]
total byte size of items in np_array:12

NumPy ndarray Vs. Python list 結構:

NumPy ndarray:存儲的是數組裡元素的值

一個指向數據(內存或內存映射文件中的一塊數據)的指針。
數據類型或 dtype,描述在數組中的固定大小值的格子。
一個表示數組形狀(shape)的元組,表示各維度大小的元組。
一個跨度元組(stride),其中的整數指的是為了前進到當前維度下一個元素需要"跨過"的字節數。


Python list:存儲的是 list 元素的引用,即內存地址,不是值

NumPy ndarray Vs. Python list 計算:

NumPy ndarry 可以進行數據間的算術運算。
Python list 之間不可以直接進行算術運算

import numpy as np
list_object = [1,2,3,4,5,6]
np_array = np.array(list_object, dtype='int16')
list_object_plus= list_object + list_object
np_array_plus = np_array + np_array
np_array_minus = np_array - np_array
np_array_divide = np_array / np_array
np_array_multi = np_array * np_array
print("list_object:{}".format(list_object))
print("list_object + list_object:{}\n".format(list_object_plus))
print("np_array:{}".format(np_array))
print("np_array + np_array:{}".format(np_array_plus))
print("np_array - np_array:{}".format(np_array_minus))
print("np_array * np_array:{}".format(np_array_divide))
print("np_array / np_array:{}".format(np_array_multi))

輸出:

list_object:[1, 2, 3, 4, 5, 6]
list_object + list_object:[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]
np_array:[1 2 3 4 5 6]
np_array + np_array:[ 2 4 6 8 10 12]
np_array - np_array:[0 0 0 0 0 0]
np_array * np_array:[1. 1. 1. 1. 1. 1.]
np_array / np_array:[ 1 4 9 16 25 36]

NumPy subarray Vs. Python sublist

我們通過例子來看一下 subarray 和 sublist 的不同

import numpy as np
list_object = [1,2,3,4,5,6]
np_array = np.array(list_object, dtype='int16')
list_object_sub = list_object[0:4]
np_array_sub = np_array[0:4]
print("origin list_object:{}".format(list_object))
print("origin np_array:{}".format(np_array))
print("origin list_object_sub:{}".format(list_object_sub))
print("origin np_array_sub:{}".format(np_array_sub))
list_object_sub[0] = 0
np_array_sub[0] = 0
print("after changed list_object_sub:{}".format(list_object_sub))
print("after changed np_array_sub:{}".format(np_array_sub))
print("list_object:{}".format(list_object))
print("np_array:{}".format(np_array))

輸出:
可以看出 NumPy subarray 就是一個原 array 的一個視圖,它的改變會影響到原 array。而 Python sublist 其實是原 list 的一個淺copy,它的改動不會影響到原list。

origin list_object:[1, 2, 3, 4, 5, 6]
origin np_array:[1 2 3 4 5 6]
origin list_object_sub:[1, 2, 3, 4]
origin np_array_sub:[1 2 3 4]
after changed list_object_sub:[0, 2, 3, 4]
after changed np_array_sub:[0 2 3 4]
list_object:[1, 2, 3, 4, 5, 6]
np_array:[0 2 3 4 5 6]

NumPy ndarray Vs. Python list 總結:

NumPy ArrayPython List創建時size創建 array時,size是固定的,一旦改變size,原來的array會被刪除,重新創建一個新的arraylist 的size可以動態變化存儲方式連續內存空間不連續內存空間item 內存每個item所占內存一樣每個item所占內存可以不一樣item 類型每個item 類型必須一致每個item類型可以不一樣總體內存內存占用較少內存占用比較多用來支持動太類型矢量計算直接支持大量數學計算不直接支持
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved