# Python Numpy / Matplotlib
資訊之芽 Python 語法班 2023/06/04
鄧人豪
---
## 課程大綱 Outline
----
1. Numpy
- 建立矩陣的方法
- ndarray 基本性質與操作
- Matrix Maths
2. Matplotlib
- 折線圖 Line Chart
- 其他圖
----
## [教材連結](https://colab.research.google.com/drive/1pLagwtFbeMuHuALfNU9tAcEx-0X3s7es?usp=sharing)請點這
---
## Numpy
----
### Numpy 可以幹嘛?
- 高維度矩陣運算
- 高速計算
----
### 安裝 numpy
```
pip install numpy --user
python3 -m pip install numpy --user
```
### import numpy
```python=
import numpy as np
print(np.__version__)
```
----
### 基本矩陣
大小為 3 * 4,每格裡面是:值(Row, Col)
| 1(0, 0) | 2(0, 1) | 3(0, 2) | 4(0, 3) |
| ------- | -------- | -------- | -------- |
| 5(1, 0) | 6(1, 1) | 7(1, 2) | 8(1, 3) |
| 9(2, 0) | 10(2, 1) | 11(2, 2) | 12(2, 3) |
- Row: 行(橫的), Column: 列(直的)
- Row0: 1, 2, 3, 4
- Row1: 5, 6, 7, 8
- Col0: 1, 5, 9
- Col1: 2, 6, 10
---
## 建立矩陣的方法
----
### 建立基本矩陣
用 list, tuple 或任何 array-like object 都可建立矩陣
```python=
import numpy as np
arr_list = np.array([1, 2, 3, 4, 5]) # 由 list 建立
arr_tuple = np.array((1, 2, 3, 4, 5)) # 由 tuple 建立
arr_range = np.array(range(1, 6)) # 由 range 建立
print(arr_list) # [1 2 3 4 5]
print(arr_tuple) # [1 2 3 4 5]
print(arr_range) # [1 2 3 4 5]
print(type(arr_list), type(arr_tuple), type(arr_range)) # <class 'numpy.ndarray'> <class 'numpy.ndarray'> <class 'numpy.ndarray'>
```
----
### 建立特殊矩陣 - 1
```python=
# np.zeros(shape): 建立 elements 都為 0 的矩陣
arr_0 = np.zeros((3, 4)) # shape = (3, 4)
print(arr_0)
# [[0. 0. 0. 0.]
# [0. 0. 0. 0.]
# [0. 0. 0. 0.]]
```
----
### 建立特殊矩陣 - 2
```python=
# np.ones(shape): 建立 elements 都為 1 的矩陣
arr_1 = np.ones((3, 4)) # shape = (3, 4)
print(arr_1)
# [[1. 1. 1. 1.]
# [1. 1. 1. 1.]
# [1. 1. 1. 1.]]
```
----
### 建立特殊矩陣 - 3
```python=
# np.full(shape, value): 建立 elements 都為 value 的矩陣are value
arr_full = np.full((3, 4), 5) # shape = (3, 4), value = 5
print(arr_full)
# [[5 5 5 5]
# [5 5 5 5]
# [5 5 5 5]]
```
----
### 建立特殊矩陣 - 4
```python=
# np.eye(n): 建立 n x n 的單位矩陣(identity matrix)
arr_eye = np.eye(3)
print(arr_eye)
# [[1. 0. 0.]
# [0. 1. 0.]
# [0. 0. 1.]]
```
----
### 建立特殊矩陣 - 5
```python=
# np.random.random(shape): 建立 elements 都為在 [0, 1) 範圍內隨機值的矩陣
arr_random = np.random.random((3, 4)) # shape = (3, 4)
print(arr_random)
# [[0.09919389 0.51211242 0.58016963 0.17999457]
# [0.49816204 0.72914405 0.01768119 0.86763625]
# [0.89068661 0.0849361 0.72184463 0.75884479]]
```
----
### 等差數列 - 1
```python=
# np.arange(stop): 建立 elements 為從 0 到 stop - 1 的矩陣
arr_arange1 = np.arange(5) # stop = 5
print(arr_arange1) # [0 1 2 3 4]
# np.arange(start, stop): 建立 elements 為從 start 到 stop - 1 的矩陣
arr_arange2 = np.arange(1, 5) # start = 1, stop = 5
print(arr_arange2) # [1 2 3 4]
# np.arange(start, stop, step): 建立 elements 為從 start 到 stop - 1,間隔為 step 的矩陣
arr_arange3 = np.arange(1, 5, 2) # start = 1, stop = 5, step = 2
print(arr_arange3) # [1 3]
```
----
### 等差數列 - 2
```python=
# np.linspace(start, stop, num=50, endpoint=True)
# 建立 elements 為從 start 到 stop、總共 num 個的矩陣
# endpoint: 假如為 True,stop 會是最後一個 sample,間隔為 (stop - start) / (num - 1)
# 否則 stop 不會是最後一個 sample,間隔為 (stop - start) / num。預設為 True。
arr_linspace1 = np.linspace(1, 5, 5) # start = 1, stop = 5, num = 5
print(arr_linspace1) # [1. 2. 3. 4. 5.]
arr_linspace2 = np.linspace(1, 5, 5, endpoint=False) # start = 1, stop = 5, num = 5, endpoint = False
print(arr_linspace2) # [1. 1.8 2.6 3.4 4.2]
```
----
### Questions?
---
## ndarray 基本性質與操作
----
### ndarray 基本性質 - 1
```python=
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr)
print(arr.shape) # (2, 3): 代表 2 rows, 3 columns
print(arr.ndim) # 2: 代表 2 dimensions
print(arr.size) # 6: 代表 6 elements
print(arr.dtype) # int64: 代表 elements are int64 type
```
----
### ndarray 基本性質 - 2
```python=
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]], dtype=np.float64)
print(arr)
print(arr.shape) # (2, 2, 3): 代表 2 layers, 2 rows, 3 columns
print(arr.ndim) # 3: 代表 3 dimensions
print(arr.size) # 12: 代表 12 elements
print(arr.dtype) # float64: 代表 elements are float64 type
```
----
### Transpose Matrix 轉置矩陣
```python=
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr)
# [[1 2 3]
# [4 5 6]]
print(arr.T) # ndarray.T 代表 transpose
# [[1 4]
# [2 5]
# [3 6]]
```
----
### 轉換型態
```python=
# change the type of elements in ndarray
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr)
# [[1 2 3]
# [4 5 6]]
print(arr.dtype) # int64
arr = arr.astype(np.float64) # change type to float64
print(arr)
# [[1. 2. 3.]
# [4. 5. 6.]]
print(arr.dtype) # float64
```
----
### 改變形狀
```python=
# reshape ndarray: arr.reshape(new_shape)
arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
arr = arr.reshape((3, 4))
print(arr)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
arr = arr.reshape((2, -1)) # -1: 自動計算
print(arr)
# [[ 0 1 2 3 4 5]
# [ 6 7 8 9 10 11]]
```
----
### Array Indexing
```python=
# one dimensional array indexing
arr = np.arange(10)
print(arr) # [0 1 2 3 4 5 6 7 8 9]
print(arr[5]) # 5
```
```python=
# two dimensional array indexing: arr[row, column]
arr = np.arange(12).reshape((3, 4))
print(arr)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(arr[1, 2]) # 6
print(arr[2, 3]) # 11
```
----
### One Dimensional Array Slicing
```python=
# one dimensional array slicing: arr[start:stop:step],不包括 stop
arr = np.arange(10)
print(arr) # [0 1 2 3 4 5 6 7 8 9]
print(arr[2:5]) # [2 3 4]
print(arr[2:5:2]) # [2 4]
print(arr[2:]) # [2 3 4 5 6 7 8 9]
print(arr[2:-1]) # [2 3 4 5 6 7 8]
print(arr[:5]) # [0 1 2 3 4]
print(arr[:]) # [0 1 2 3 4 5 6 7 8 9]
print(arr[::2]) # [0 2 4 6 8]
print(arr[::-1]) # [9 8 7 6 5 4 3 2 1 0]
```
----
### Two Dimensional Array Slicing - 1
```python=
# arr[start:stop:step, start:stop:step]
arr = np.arange(12).reshape((3, 4))
print(arr)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(arr[1:3, 2:4])
# [[ 6 7]
# [10 11]]
print(arr[1:3, :])
# [[ 4 5 6 7]
# [ 8 9 10 11]]
```
----
### Two Dimensional Array Slicing - 2
```python=
print(arr[:, 1:3])
# [[ 1 2]
# [ 5 6]
# [ 9 10]]
print(arr[:, ::2])
# [[ 0 2]
# [ 4 6]
# [ 8 10]]
print(arr[::-1, ::-1])
# [[11 10 9 8]
# [ 7 6 5 4]
# [ 3 2 1 0]]
```
----
### Array Filtering
```python=
arr = np.arange(12)
print(arr) # [0 1 2 3 4 5 6 7 8 9 10 11]
print(arr > 5) # [False False False False False False True True True True True True]
print(arr[arr > 5]) # [ 6 7 8 9 10 11]
print(arr[(arr > 5) & (arr < 10)]) # [6 7 8 9]
print(arr[(arr < 5) | (arr > 10)]) # [ 0 1 2 3 4 11]
arr[(arr > 5)] = 0
print(arr) # [0 1 2 3 4 5 0 0 0 0 0 0]
```
----
### Array Copy
```python=
arr = np.arange(10)
print(arr) # [0 1 2 3 4 5 6 7 8 9]
arr2 = arr
arr2[0] = 100
print(arr) # [100 1 2 3 4 5 6 7 8 9]
print(arr2) # [100 1 2 3 4 5 6 7 8 9]
arr3 = arr.copy()
arr3[0] = 200
print(arr) # [100 1 2 3 4 5 6 7 8 9]
print(arr3) # [200 1 2 3 4 5 6 7 8 9]
```
----
### Array Iterating
```python=
arr = np.arange(12).reshape((3, 4))
print(arr)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
for row in arr:
for element in row:
print(element)
```
----
### Questions?
---
## Matrix Maths
----
### Math Operation
```python=
arr = np.arange(12)
print(arr) # [0 1 2 3 4 5 6 7 8 9 10 11]
print(arr + 1) # [ 1 2 3 4 5 6 7 8 9 10 11 12]
print(arr - 1) # [-1 0 1 2 3 4 5 6 7 8 9 10]
print(arr * 2) # [ 0 2 4 6 8 10 12 14 16 18 20 22]
print(arr / 2) # [0. 0.5 1. 1.5 2. 2.5 3. 3.5 4. 4.5 5. 5.5]
print(arr ** 2) # [ 0 1 4 9 16 25 36 49 64 81 100 121]
print(arr % 2) # [0 1 0 1 0 1 0 1 0 1 0 1]
print(arr // 2) # [0 0 1 1 2 2 3 3 4 4 5 5]
```
----
### Matrix Multiplication
```python=
# array dot operation
arr1 = np.arange(6).reshape((2, 3))
arr2 = np.arange(6).reshape((3, 2))
print(arr1)
# [[0 1 2]
# [3 4 5]]
print(arr2)
# [[0 1]
# [2 3]
# [4 5]]
print(np.dot(arr1, arr2))
# [[10 13] # 0*0+1*2+2*4, 0*1+1*3+2*5
# [28 40]] # 3*0+4*2+5*4, 3*1+4*3+5*5
```
----
### Questions?
---
## Matplotlib
----
### Matplotlib 可以幹嘛?
- 數據與資料視覺化
- 畫圖功能齊全
----
### 安裝 matplotlib
```
pip install matplotlib --user
python3 -m pip install matplotlib --user
```
### import matplotlib
```python=
import matplotlib.pyplot as plt
```
---
## 折線圖 Line Chart
----
### 只有 y 值的折線圖
```python=
# plot by 1d ndarray or list
y = [2, 3, 1, 4]
plt.plot(y) # only plot by y value
plt.show() # 顯示整張圖
```
<p float="left">
<img src="https://hackmd.io/_uploads/r1_wxZu42.png" width="40%" style="background-color:white;"/>
</p>
----
### 有 x 與 y 值的折線圖
```python=
# plot by x and y
x = np.arange(0, 5, 0.5) # [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5]
y = np.sin(x) # 每個 x 對應的 sin 值 [0., 0.47942554, 0.84147098, 0.99749499, 0.90929743, 0.59847214, 0.14112001, -0.35078323, -0.7568025, -0.97753012]
plt.plot(x, y)
plt.show()
```
<p float="left">
<img src="https://hackmd.io/_uploads/HyJB-bdNn.png" width="40%" style="background-color:white;"/>
</p>
----
### 修改線的格式
```python=
# plot by x and y
x = np.arange(0, 5, 0.5) # [0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5]
y = np.sin(x) # 每個 x 對應的 sin 值
# marker: 代表點的樣式, linestyle: 代表線的樣式, color: 代表線的顏色
plt.plot(x, y, marker='o', linestyle='--', color='g')
plt.show()
```
<p float="left">
<img src="https://hackmd.io/_uploads/BJPhb-_E2.png" width="50%" style="background-color:white;"/>
</p>
----
### 多條線段
```python=
# plot two lines
x = np.arange(0, 5, 0.5) # [0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5]
y1 = np.sin(x) # 每個 x 對應的 sin 值
y2 = np.cos(x) # 每個 x 對應的 cos 值
plt.plot(x, y1, marker='o', linestyle='--', color='g', label='sin')
plt.plot(x, y2, marker='x', linestyle='-.', color='r', label='cos')
plt.xlabel("x label") # x 軸的 label
plt.ylabel("y label") # y 軸的 label
plt.legend(title="Legend title") # legend 中文為圖例,顯示每條線的 label,title: legend 的 title
plt.title("This is title") # 圖表的 title
plt.show()
```
圖附於下一頁
----
<p float="left">
<img src="https://hackmd.io/_uploads/Sks7zZd43.png" width="80%" style="background-color:white;"/>
</p>
----
### Questions?
---
## 其他圖
----
### 分布圖
```python=
# scatter plot
x = np.arange(0, 5, 0.5) # [0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5]
y = np.sin(x) # 每個 x 對應的 sin 值
plt.scatter(x, y)
plt.show()
```
<p float="left">
<img src="https://hackmd.io/_uploads/ry79MW_43.png" width="45%" style="background-color:white;"/>
</p>
----
### 長條圖
```python=
# bar plot
x = np.array(["A", "B", "C", "D"]) # x 軸的 label
y = np.array([3, 8, 1, 10]) # 每個 x 對應的值
plt.bar(x,y)
plt.show()
```
<p float="left">
<img src="https://hackmd.io/_uploads/HJz6zWuEn.png" width="45%" style="background-color:white;"/>
</p>
----
### 直方圖
```python=
# histogram
x = np.random.normal(170, 10, 250) # 平均值 170,標準差 10,共 250 個數字,符合常態分佈
print(x.shape) # (250,)
plt.hist(x)
plt.show()
```
<p float="left">
<img src="https://hackmd.io/_uploads/rktZ7bdN2.png" width="40%" style="background-color:white;"/>
</p>
----
### 圓餅圖
```python=
# pie chart
mylabels = ["Apples", "Bananas", "Cherries", "Watermelons"] # 每個 label
y = [35, 25, 25, 15] # 每個 label 的值
myexplode = [0.2, 0, 0, 0] # 每個部分離開中心的距離
plt.pie(y, labels=mylabels, explode=myexplode, shadow=True) # shadow: 是否要陰影
plt.show()
```
<p float="left">
<img src="https://hackmd.io/_uploads/By4gN-uVh.png" width="40%" style="background-color:white;"/>
</p>
----
### 顯示多張子圖
```python=
# subplot 2 rows and 3 columns
x = np.arange(0, 5, 0.5) # [0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5]
# adjust figure size
plt.figure(figsize=(10, 7)) # 定義 figure 大小 (width, height)
plt.subplot(2, 3, 1) # 2 rows, 3 columns, 1st plot
plt.plot(x, x)
plt.title("Subplot 1")
plt.subplot(2, 3, 2) # 2 rows, 3 columns, 2nd plot
plt.plot(x, x**2)
plt.title("Subplot 2")
plt.subplot(2, 3, 3) # 2 rows, 3 columns, 3rd plot
plt.plot(x, x**3)
plt.title("Subplot 3")
plt.subplot(2, 3, 4) # 2 rows, 3 columns, 4th plot
plt.plot(x, x**4)
plt.title("Subplot 4")
plt.subplot(2, 3, 5) # 2 rows, 3 columns, 5th plot
plt.plot(x, x**5)
plt.title("Subplot 5")
plt.subplot(2, 3, 6) # 2 rows, 3 columns, 6th plot
plt.plot(x, x**6)
plt.title("Subplot 6")
plt.suptitle("This is suptitle") # 整個圖表的 title
plt.show()
```
圖附於下一頁
----
<p float="left">
<img src="https://hackmd.io/_uploads/HyJUV-_Nn.png" width="80%" style="background-color:white;"/>
</p>
----
### Questions?
---
# Thanks!
{"metaMigratedAt":"2023-06-18T03:47:42.597Z","metaMigratedFrom":"YAML","title":"Python Numpy / Matplotlib - 資訊之芽 2023 python 語法班","breaks":true,"contributors":"[{\"id\":\"4f7954d3-8899-4aaf-a4b8-756ab47563e1\",\"add\":15942,\"del\":3316}]"}