NumPy 數組:簡介 [含示例]
已發表: 2022-12-08想要開始使用 NumPy? 本指南將教您 Python 中 NumPy 數組的基礎知識。
作為第一步,您將了解 NumPy 數組與 Python 列表的工作方式有何不同。 然後,您將學習幾種創建 NumPy 數組並對它們執行基本操作的方法。
讓我們開始!
NumPy 數組基礎知識
NumPy 是用於科學計算和數據分析的最流行的 Python 庫之一。 NumPy 中的基本數據結構是 N 維數組(ND 數組)。 它們具有廣播功能,允許我們對操作進行矢量化以提高速度,並使用內置的數學函數來提高性能。
要開始使用 NumPy,您應該首先安裝該庫並將其導入您的工作環境。 它作為可通過 pip 安裝的 PyPI 包提供。
要安裝 NumPy,請打開終端並運行以下命令:
pip3 install numpy
安裝 NumPy 後,您可以使用別名將其導入到您的工作環境中。 通常的別名是np
。
import numpy as np
注意:在別名
np
下導入 NumPy 不是必需的,而是推薦的約定。
Python 列表與 NumPy 數組
考慮以下 Python 數字列表:
py_list = [1,2,3,4]
您可以通過以列表作為參數調用np.array()
函數,從現有列表中獲取 NumPy 數組。
np_arr1 = np.array(py_list) print(np_arr1) [1 2 3 4]
要檢查np_arr1
的類型,您可以調用內置的type()
函數,您會看到它是ndarray
,這是 NumPy 中的基本數據結構。
type(np_arr1) # numpy.ndarray
儘管 Python 列表和 NumPy 數組看起來很相似,但還是有一些區別:
- Python 列表可以包含不同數據類型的對象,而 NumPy 數組包含相同數據類型的元素。 默認數據類型為精度為 64 位的浮點數 (float64)。
- Python 列表的元素不一定存儲在內存中的連續位置。 但是,NumPy 數組的元素存儲在內存中的連續塊中。 因此,查找和訪問元素的速度更快。
讓我們回顧一下其他幾個差異。
廣播
NumPy 數組的一個強大功能是廣播。 假設我們想將 2 添加到np_arr1
和py_list
的所有元素。
讓我們嘗試將 2 添加到py_list
,看看會發生什麼:
>>> py_list + 2
我們看到我們得到一個 TypeError,說明我們只能連接兩個列表,並且不支持像這樣添加 py_list + 2。
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-5-c0f9974899df> in <module> ----> 1 py_list + 2 TypeError: can only concatenate list (not "int") to list
讓我們在數組np_arr1
上嘗試相同的操作。
>>> np_arr1 + 2
在結果中,我們看到數組的每個元素都添加了 2。
array([3, 4, 5, 6])
這是因為 NumPy 將標量 2 隱式廣播到兼容形狀的數組以產生此結果。
矢量化
NumPy 數組支持矢量化以實現更快的元素操作。 假設我們想要找到兩個數組的逐元素總和。
在列表上使用簡單的+
操作將返回兩個列表的串聯(這不是我們想要的!)。
>>> py_list + py_list # [1, 2, 3, 4, 1, 2, 3, 4]
但是對 NumPy 數組np_arr1
的相同操作返回np_arr1
與自身的逐元素總和。
>>> np_arr1 + np_arr1 # array([2, 4, 6, 8])
同樣,嵌套列表在結構上可能類似於 N 維 NumPy 數組。 但是,到目前為止討論的差異仍然存在。
nested_list = [[1,2],[3,4],[5,6]] np_arr2 = np.array(nested_list) print(np_arr2)
[[1 2] [3 4] [5 6]]
如何創建 NumPy 數組
您始終可以使用np.array(list-obj)
從現有的 Python 列表創建 NumPy 數組。 但是,這不是最有效的方法。
相反,您可以使用多個內置函數來創建特定形狀的數組。 數組的形狀是一個元組,表示數組沿每個維度的大小。 例如,兩行兩列的 2×2 數組的形狀是 (2,2)。 在本節中,我們將學習如何使用其中一些內置函數。
創建零和一的數組
創建一個由全零或全一填充的特定維度數組通常很有幫助。 然後在程序的後續步驟中使用和修改它們。
我們可以使用zeros()
函數來創建一個零數組。 將所需數組的形狀作為元組傳遞: np.zeros(shape)
。
array0 = np.zeros((3,3)) print(array0)
這是輸出,一個二維零數組:
[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]]
您可以訪問 NumPy 數組的屬性,調用dtype
和shape
等屬性,使用點符號,如下所示:
print(array0.dtype) # float64 print(array0.shape) # (3, 3)
要獲得一個數組,您可以使用np.ones()
函數。
array1 = np.ones((3,3)) print(array1)
[[1. 1. 1.] [1. 1. 1.] [1. 1. 1.]]
創建單位矩陣
單位矩陣廣泛用於線性代數的多種應用中。 您可以使用np.eye()
函數創建單位矩陣。 np.eye()
函數只接受一個參數:矩陣的順序 ( n
)。
arrayi = np.eye(3) print(arrayi)
[[1. 0. 0.] [0. 1. 0.] [0. 0. 1.]]
創建隨機數數組
您還可以創建特定形狀的數組,其中填充了從特定分佈中抽取的隨機數。 常用的概率分佈有均勻分佈和標準正態分佈。
randn()
函數是 NumPy random
模塊的一部分,可用於生成從標準正態分佈中採樣的數字數組。 標準正態分佈是具有零均值和單位方差的高斯分佈。
std_arr = np.random.randn(3,4) print(std_arr)
[[-0.13604072 1.21884359 2.06850932 0.78212093] [ 0.44314719 -0.78084801 -0.70517138 1.17984949] [ 1.13214829 1.02339351 0.15317809 1.83191128]]
np.random.rand()
返回區間 [0,1) 內均勻分佈的數字樣本數組。
uniform_arr = np.random.rand(2,3) print(uniform_arr)
[[0.90470384 0.18877441 0.10021817] [0.741 0.10657658 0.71334643]]
您還可以使用 NumPy 隨機模塊中的randint()
函數創建一個隨機整數數組。 np.random.randint(low, high, size)
返回一個整數數組。 數組的形狀是從size
參數推斷出來的,整數取區間[low,high)
中的值。
這是一個例子:
int_arr = np.random.randint(1,100,(2,3)) print(int_arr)
[[53 89 33] [24 85 33]]
其他有用的內置函數
接下來,讓我們了解一些其他有用的函數來創建 NumPy 數組。
arange()
函數以步長值的step
返回start
和stop
值之間的數字數組: start
、 start + step
、 start + 2*step
up to but not including stop
。 start
和step
值是可選的。 默認步長為 1,默認起始值為 0。
在此示例中, array_a
是一個數字數組,從 1 開始,但不包括 10,步長為 0.5。
array_a = np.arange(1,10,0.5) print(array_a)
[1. 1.5 2. 2.5 3. 3.5 4. 4.5 5. 5.5 6. 6.5 7. 7.5 8. 8.5 9. 9.5]
您還可以使用np.linspace()
創建間隔均勻的數字數組。 使用np.linspace(start, stop, num)
獲取start
和stop
值之間均勻分佈的num
個數字的數組。
這裡, arr_lin
是區間 [1,10] 中 5 個均勻分佈的數字的數組。
array_lin = np.linspace(1,10,5) print(array_lin)
[ 1. 3.25 5.5 7.75 10. ]
同理, arr_lin2
是區間 [1,20] 中 10 個等距數字的數組。
array_lin2 = np.linspace(1,20,10) print(array_lin2)
[ 1. 3.11111111 5.22222222 7.33333333 9.44444444 11.55555556 13.66666667 15.77777778 17.88888889 20. ]
與arange()
函數不同, linspace()
函數默認包含端點。
NumPy 數組的基本操作
接下來,讓我們回顧一下 NumPy 數組的一些基本操作。
尋找最小和最大元素
每當我們使用 NumPy 的隨機模塊中的函數來創建數組時,每次運行代碼時我們都會得到不同的結果。 為了獲得可重現的結果,我們應該設置一個種子: np.random.seed(seed_value)
。
在下面的示例中,我設置了可重複性的種子, int_arr1
是區間 [1,100) 中七個隨機整數的數組。
np.random.seed(27) int_arr1 = np.random.randint(1,100,7) print(int_arr1) # [20 57 73 32 57 38 25]
- 要找到數組中的最大元素,可以調用數組對象
int_arr1
上的max()
方法,然後 - 要找到數組中的最小元素,可以調用數組對象
int_arr1
上的min()
方法。
int_arr1.max() # 73 int_arr1.min() # 20
查找最大和最小元素的索引
有時,您可能需要找到最大和最小元素的索引。 為此,您可以調用數組對象的argmax()
和 argmin( argmin()
方法。
這裡,最大元素 73 出現在索引 2 處。
int_arr1.argmax() # 2
最小元素 20 出現在索引 0 處。
int_arr1.argmin() # 0
您還可以使用
np.argmax(array)
和np.argmin(array)
分別查找最大和最小元素的索引。 了解有關 NumPyargmax()
函數的更多信息。
如何連接 NumPy 數組
您可能希望對 NumPy 數組執行的另一個常見操作是串聯。
使用 vstack 的垂直串聯
您可以使用vstack()
函數垂直連接數組。
這是一個例子。 arr1
是一個兩行三列的數組, arr2
是兩行三列的零數組。
arr1 = np.ones((2,3)) arr2 = np.zeros((2,3))
我們可以使用vstack()
函數垂直連接這兩個數組,如下所示:
np.vstack((arr1,arr2))
array([[1., 1., 1.], [1., 1., 1.], [0., 0., 0.], [0., 0., 0.]])
由於堆疊是垂直發生的,因此兩個數組的列數應該相同。
讓我們將arr2
的形狀更改為 (2,2)。 它現在有兩行和兩列。
arr1 = np.ones((2,3)) arr2 = np.zeros((2,2)) np.vstack((arr1,arr2))
因此,垂直連接是不可能的,我們得到一個 ValueError。
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-21-d5d3bf37fc21> in <module> ----> 1 np.vstack((arr1,arr2)) ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 3 and the array at index 1 has size 2
使用 hstack 的水平連接
您可以使用hstack()
函數水平連接 NumPy 數組,如下所示。
arr1 = np.ones((3,3)) arr2 = np.zeros((3,2))
np.hstack((arr1,arr2))
因為堆疊是水平進行的,所以輸入數組的行數應該相同。 這裡, arr1
和arr2
都有三行。
array([[1., 1., 1., 0., 0.], [1., 1., 1., 0., 0.], [1., 1., 1., 0., 0.]])
使用連接
您還可以使用concatenate()
函數沿特定軸連接 NumPy 數組。 將可選的axis
參數設置為您想要連接的軸; 軸的默認值為零。
這裡有一些例子:
arr1 = np.ones((2,3)) arr2 = np.zeros((2,3))
當我們沒有指定要連接的軸時,數組將沿著軸 0 連接。在結果數組中,第二個數組arr2
添加(作為行)在第一個數組下面。
np.concatenate((arr1,arr2))
array([[1., 1., 1.], [1., 1., 1.], [0., 0., 0.], [0., 0., 0.]])
當我們指定axis = 1
時,我們得到以下結果。 arr2
連接(作為列)在第一個數組arr1
旁邊。
np.concatenate((arr1,arr2),axis=1)
array([[1., 1., 1., 0., 0., 0.], [1., 1., 1., 0., 0., 0.]])
與hstack()
和vstack()
函數一樣,數組沿連接軸的維度應該匹配。
結論
在本教程中,您了解了 NumPy 數組和 Python 列表之間的區別,重點介紹了 N 維數組在速度和效率方面的優勢。
您還學習了幾個有用的函數來創建特定維度的數組並執行常見操作,例如查找最小和最大元素、連接數組等。
接下來,學習如何重塑 NumPy 數組。