# Numpy ###### tags: `Python` `Numpy` #### 2022/03/17 by JohnAxer ## 基本觀念 - Numpy 是一個多維陣列的運算套件,可以用來進行矩陣相關運算。 - 在數學中的「矩陣」(Matrix),如果要丟到程式當中運算,我們通常會利用「陣列」(array) 來儲存。Numpy 提供一個可以高效的陣列和許多陣列計算函式,非常適合用來儲存科學或工程計算所需的資料,並作相關的計算。<span style="color: red;">但是請注意:陣列並不等於矩陣,所以有些計算方式是數學上的矩陣所沒有的。</span> - 在 Numpy 中,陣列透過 ndarray 物件來實現。 ## 認識陣列(矩陣) - 假設陣列 A 如下: $$ A = \begin{bmatrix} 11 & 12 \\ 21 & 22 \\ 31 & 32 \end{bmatrix} $$ - 陣列 A 為「3列(row) 2行(column)」,其中列為橫的,行為直的。 - 在 numpy 中,利用元組(tuple) 紀錄陣列的形狀(shape),A 為 (3, 2) 的矩陣。 - 陣列大小(size) 其實就是陣列中的元素個數,所以,陣列 A 的大小為 6。 - 陣列 A 是一個 2維矩陣,所以,陣列 A 的維度(ndim) 為 2。 - 可以利用 A[2, 1] 或 A[2][1] 存取到最右下角的元素,其值為「32」。注意:如同串列(list)一樣,列索引值和行索引值都是從 0 開始。 - 一個 n 維陣列,會有 n 個軸(axis)。以陣列 A 為例,陣列 A 有兩個軸,那誰是axis 0呢?很簡單,看下圖就明白了。 ![](https://hackmd.io/_uploads/BJtM_Ogz5.png) - 程式碼 ```python= import numpy as np a = np.array([[11, 12], [21, 22], [31, 32]]) print(type(a)) #顯示變數a的資料型態,結果為 ndarray print(a.shape) #(3, 2) print(a.size) #6 print(a.ndim) #2 print(a[2, 1]) #32 ``` ## 陣列建立 - **透過 List 轉換** - 一維陣列 ```python= import numpy as np a1 = np.array([10, 20, 30, 40]) ``` 這個會得到一個 1 維陣列如下: $$ a1 = \begin{bmatrix} 10 & 20 & 30 & 40 \end{bmatrix} $$ - 二維陣列 ```python= import numpy as np a2 = np.array([[11, 12, 13], [21, 22, 23]]) ``` 這個程式得到一個 2 維陣列如下: $$ a2 = \begin{bmatrix} 11 & 12 & 13 \\ 21 & 22 & 23 \end{bmatrix} $$ - 陣列形狀轉換 有時候,我們可以先輸入一個串列後,再改變形狀,例如: ```python= import numpy as np a3 = np.array([11, 12, 21, 22, 31, 32]) a3 = a3.reshape(3, 2) ``` 執行後,會得到一個 3*2 的陣列如下: $$ a3 =\begin{bmatrix} 11 & 12 \\ 21 & 22 \\ 31 & 32 \end{bmatrix} $$ 那麼下面這個程式,產生的陣列應該為何? ```python= import numpy as np a3 = np.array([11, 12, 21, 22, 31, 32]) a3 = a3.reshape(2, 3) ``` - **利用 arange 函數產生** - arange 函數的用法基本上和 range 一樣,唯一的差別是 arange 可以產生浮點數的數列。 ```python= import numpy as np a4 = np.arange(1, 5, 0.5) print(a4) ``` 結果如下:(注意: 1. 表示為 1 的浮點數) $$ a4 = \begin{bmatrix} 1. & 1.5 & 2. & 2.5 & 3. & 3.5 & 4. & 4.5 \end{bmatrix} $$ - **利用 linspace 函數產生** - linspace 函數可以將指定區間平均分為 n-1 等分。其形式如下: linspace(start, end, n) - 注意到 linspace 函數預設是有包括 start 和 end 兩點。 - 考慮以下程式,其執行結果為何? ```python= import numpy as np s1 = np.linspace(0, 5, 5) s2 = np.linspace(0, 5, 6) ``` $$ s1 = \begin{bmatrix} 0. & 1.25 & 2.5 & 3.75 & 5. \end{bmatrix} $$ $$ s2 = \begin{bmatrix} 0. & 1. & 2. & 3. & 4. & 5. \end{bmatrix} $$ - **利用隨機亂數產生** - 除了 python 內建的 random 模組可以產生隨機亂數外,Numpy 也提供更強大的 random 模組,包括有: - numpy.random.rand(): 產生 [0~1) 之間的隨機亂數(浮點數) - numpy.random.normal(): 產生常態分配的隨機亂數(浮點數) - - **特殊的陣列** - **元素都是 0 的陣列** ```python= import numpy as np a5 = np.zeros(5) a6 = np.zeros((2,3)) a7 = np.zeros((2,3), dtype=int) ``` 其中 a5、a6 陣列內的元素值均為 0 且為浮點數;a7 陣列內的元素值為整數 0。結果如下: $$ a5 = \begin{bmatrix} 0. & 0. & 0. & 0. & 0. \end{bmatrix} $$ $$ a6 = \begin{bmatrix} 0. & 0. & 0. \\ 0. & 0. & 0. \end{bmatrix} $$ $$ a7 = \begin{bmatrix} 0 & 0 & 0 \\ 0 & 0 & 0 \end{bmatrix} $$ - **元素都是 1 的陣列** ```python= import numpy as np a8 = np.ones(5) a9 = np.ones((2,3)) a10 = np.ones((2,3), dtype=int) ``` 其中 a8、a9 陣列內的元素值均為 1 且為浮點數;a10 陣列內的元素值為整數 1。結果如下: $$ a8 = \begin{bmatrix} 1. & 1. & 1. & 1. & 1. \end{bmatrix} $$ $$ a9 = \begin{bmatrix} 1. & 1. & 1. \\ 1. & 1. & 1. \end{bmatrix} $$ $$ a10 = \begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \end{bmatrix} $$ - **單位元素陣列** ```python= import numpy as np e1 = np.eye(3) e2 = np.eye(2,3) e3 = np.eye(3, dtype=int) ``` ## 陣列的運算 - 假設有兩個陣列 $$ a = \begin{bmatrix} 1 & 2 \\ 3 & 4 \\ 5 & 6 \\ \end{bmatrix}\ \ \ \ \ \ \ \ \ \ b = \begin{bmatrix} 1 & 3 \\ 2 & 2 \\ 3 & 1 \\ \end{bmatrix} $$ - 純量與陣列運算 - 純量會進行廣播(boardcast)運算。 - 例如:c = 5 + a,則 $$ c = \begin{bmatrix} 6 & 7 \\ 8 & 9 \\ 10 & 11 \\ \end{bmatrix} $$ - python 的運算子(符號)均可以用,包括:+、-、*、/、//、%、** ```python= import numpy as np a = np.array([1, 2, 3, 4, 5, 6]) a = a.reshape(3, 2) c = 5 + a print(c) ``` - 陣列與陣列運算 - 陣列間運算的條件: - 兩個陣列的形狀(shape)相同。 - 兩個陣列形狀(shape)不相同,但是其中一個陣列可以廣播成另一個形狀。 - python 的運算子(符號)均可以用,包括:+、-、*、/、//、%、** - 例如: d = a + b $$ d = \begin{bmatrix} 1 & 2 \\ 3 & 4 \\ 5 & 6 \\ \end{bmatrix}+ \begin{bmatrix} 1 & 3 \\ 2 & 2 \\ 3 & 1 \\ \end{bmatrix}= \begin{bmatrix} 2 & 5 \\ 5 & 6 \\ 8 & 7 \\ \end{bmatrix} $$ ```python= import numpy as np a = np.array([1, 2, 3, 4, 5, 6]) b = np.array([1, 3, 2, 2, 3, 1]) a = a.reshape(3, 2) b = e.resahpe(3, 2) d = a + b print(d) ``` - 數學矩陣運算 - 設有一個矩陣 e 如下 $$ e = \begin{bmatrix} 1 & 2 \\ 2 & 1 \\ \end{bmatrix} $$ - 矩陣 a 與 e 做矩陣乘法,可用運算符號「@」,則 f = a @ e 結果如下: $$ f = \begin{bmatrix} 1 & 2 \\ 3 & 4 \\ 5 & 6 \\ \end{bmatrix}\times \begin{bmatrix} 1 & 2 \\ 2 & 1 \\ \end{bmatrix} = \begin{bmatrix} 5 & 4 \\ 11 & 10 \\ 17 & 16 \\ \end{bmatrix} $$ ```python= import numpy as np a = np.array([1, 2, 3, 4, 5, 6]) e = np.array([1, 2, 2, 1]) a = a.reshape(3, 2) e = e.resahpe(2, 2) f = a @ e print(f) ```