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_arr1py_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)。 在本節中,我們將學習如何使用其中一些內置函數。

如何創建 NumPy 數組

創建零和一的數組

創建一個由全零或全一填充的特定維度數組通常很有幫助。 然後在程序的後續步驟中使用和修改它們。

我們可以使用zeros()函數來創建一個零數組。 將所需數組的形狀作為元組傳遞: np.zeros(shape)

 array0 = np.zeros((3,3)) print(array0)

這是輸出,一個二維零數組:

 [[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]]

您可以訪問 NumPy 數組的屬性,調用dtypeshape等屬性,使用點符號,如下所示:

 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返回startstop值之間的數字數組: startstart + stepstart + 2*step up to but not including stopstartstep值是可選的。 默認步長為 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)獲取startstop值之間均勻分佈的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)分別查找最大和最小元素的索引。 了解有關 NumPy argmax()函數的更多信息。

如何連接 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))

因為堆疊是水平進行的,所以輸入數組的數應該相同。 這裡, arr1arr2都有三行。

 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 數組。