# numpy
[](https://hackmd.io/@RogelioKG/numpy)
## Note
### axis
+ <mark>array[層][列][行]</mark>
+ <mark>array.shape == (層, 列, 行)</mark>
+ 軸
> 第 -1 軸代表行,那代表沿著第 -1 軸前進時,只有行會變動。\
> 比如第 1 行、第 2 行 ... 記住這點,小心別搞錯方向。\
> 以此類推,我們可得出:第 i 軸上有 shape[i] 個元素。
+ i = 0:第 0 軸 (層)
+ i = 1:第 1 軸 (列)
+ i = 2:第 2 軸 (行)
+ i = -1:最終軸 (行)
+ <mark>轉置:reverse 所有軸</mark>
> 原本的第 0、1、2 軸,變成第 2、1、0 軸
+ 注意
|🚨 <span class="caution">CAUTION</span>|
|:---|
| numpy array 預設記憶體布局從「最終軸」開始連續排列,<br>對於需要大量迴圈計算的資料,請放入這一軸。 |
### NDA
+ 一維 NDA (轉置無效、相乘時自動調正行列、相乘結果必然是一維 NDA)
```py
np.array([2.0, 4.0]) # shape: (2,)
```
+ 二維 NDA (轉置有效)
```py
np.array([2.0, 4.0]) # shape: (1, 2)
```
+ 一維 NDA <-> 二維 NDA
```py
a = np.array([2.0, 4.0])
print(a)
# [2. 4.]
b = a[:, None]
print(b)
# [[2.]
# [4.]]
c = a[None, :]
print(c)
# [[2. 4.]]
d = b[:, 0]
print(d)
# [2. 4.]
```
+ [<mark>broadcasting</mark>](https://steam.oxxostudio.tw/category/python/numpy/numpy-broadcast.html):將小 NDA 擴展成大 NDA,以便兼容 NDA 的四則運算 (`+`、`-`、`*`、`/`)
## Class
### 陣列 [`ndarray`](https://www.delftstack.com/zh-tw/tutorial/python-numpy/numpy-ndarray/)
+ 索引方式
```py
array_3D[層, 列, 行]
array_3D[層][列][行]
array_3D[1, 2, 3] # 【第 1 層】-【第 2 列】-【第 3 行】的那個元素
array_3D[1][2][3]
array_3D[1:3, 2:4, 3:5] # 【第 1~2 層】-【第 2~3 列】-【第 3~4 行】的那些元素
array_3D[1:3][2:4][3:5]
array_3D[:, :, 1] # 【第 1 行】的那些元素
array_3D[:][:][1]
```
+ 屬性
| 屬性 | 說明 |
|------|------|
| `ndim` | 幾階張量 |
| `size` | 元素數量 |
| `shape` | 形狀 (層, 列, 行) |
| `dtype` | 資料型態 |
| `real` | 實部 |
| `imag` | 虛部 |
| `T` | 轉置 |
+ 方法
| 方法 | 說明 |
|------|------|
| `transpose()` | 轉置 |
| `sum(axis=)` | 總和 |
| `cumsum(axis=)` | 累積總和 |
| `min(axis=)` | 最小值 |
| `max(axis=)` | 最大值 |
| `mean(axis=)` | 平均數 |
| `var(axis=)` | 變異數 |
| `std(axis=)` | 標準差 |
| `item(2,3,1)` | 等同 `arr[2][3][1]` |
| `itemset((2,3,1), 10)` | 等同 `arr[2][3][1] = 10` |
| `all(axis=)` | 是否全為 True |
| `any(axis=)` | 是否有任一 True |
| `flatten()` | 壓平(深拷貝) |
| `ravel()` | 壓平(淺拷貝) |
| `reshape(shape)` | 重塑 |
| `unique(axis=)` | 挑出獨特元素並排序 |
| `clip(a_min=,a_max=)` | 元素超過 a_max 則為 a_max,少於 a_min 則為 a_min |
| `unravel_index(indices, shape)` | 將扁平索引轉為多層索引 |
+ 參數
+ `unique()`
| 參數 | 說明 |
|------|------|
| `return_index=True` | 回傳獨特陣列在原陣列第一次出現的索引 |
| `return_inverse=True` | 回傳重建原陣列所需的獨特陣列索引 |
### 資料型別 `dtype`
+ 內建型別
| 型別 | 說明 |
|------|------|
| `np.bool_` | 布林 |
| `np.string_` | ASCII 字串 |
| `np.unicode_` | Unicode 字串 |
| `np.int_` | 有號整數 (預設 int32) |
| `np.int8/16/32/64/128/256` | 指定位數有號整數 |
| `np.uint8/16/32/64/128/256` | 指定位數無號整數 |
| `np.float_` | 浮點數 (預設 float64) |
| `np.float16/32/64/80/96/128/256` | 指定位數浮點數 |
| `np.complex_` | 複數 (預設 complex128) |
| `np.complex64/128` | 指定位數複數 |
+ 自訂型別
```py
Student = np.dtype([
('name', np.str_, 16),
('grades', np.float64, (2,))
])
# struct Student
# {
# string name[16];
# float64 grades[2];
# };
arr = np.array([
('Sarah', (8.0, 7.0)),
('John', (6.0, 7.0))
], dtype=Student)
print(arr[1]["name"]) # John
print(arr[1]["grades"]) # [6. 7.]
print(arr[:]["grades"]) # [[8. 7.] [6. 7.]]
```
### 日期 `datetime64`
+ 使用
```py
# 整數:自 UNIX 紀元時間開始偏移多久
np.datetime64(1699518619, 's') # 2023-11-09T08:30:19
# 字串:轉成日期,可指定精度
np.datetime64('2023-11-09T08:30:19', 'D') # 2023-11-09
```
### 時間差 `timedelta64`
+ 使用
```py
# 整數:偏移量
np.datetime64('2009') + np.timedelta64(20, 'D') == np.datetime64('2009-01-21')
```
## Constant
### Math
+ 變數
| 常數 | 說明 |
|------|------|
| `np.pi` | 圓周率 |
| `np.e` | 自然常數 |
## Function
### Factory
+ 函數
| 函數 | 說明 |
|------|------|
| `array(array_like)` | 從陣列類型物件建立 |
| `asarray(array_like)` | 轉換為陣列 |
| `arange(start, stop, step)` | 等差數列 |
| `linspace(起點, 終點, 數量)` | 均勻分割區間 |
| `zeros(shape)` | 全零陣列 |
| `zeros_like(NDA)` | 與指定陣列同形狀的全零陣列 |
| `ones(shape)` | 全一陣列 |
| `ones_like(NDA)` | 與指定陣列同形狀的全一陣列 |
| `empty(shape)` | 未初始化陣列 |
| `empty_like(NDA)` | 與指定陣列同形狀的未初始化陣列 |
| `full(shape, 值)` | 指定值填充陣列 |
| `full_like(NDA, 值)` | 與指定陣列同形狀的指定值陣列 |
| `eye(列, 行, k=向右位移)` | 對角矩陣 |
| `identity(n)` | n 階單位矩陣 |
| `tri(n)` | n 階單位下三角矩陣 |
| `tril(列, 行, k=背對0的位移)` | 下三角矩陣 |
| `triu(列, 行, k=背對0的位移)` | 上三角矩陣 |
| `meshgrid(x座標點, y座標點)` | 網格化:返回 x 矩陣、y 矩陣 |
| `mgrid[x座標點slice, y座標點slice]` | 網格化:返回 x 矩陣、y 矩陣 (一般)|
| `ogrid[x座標點slice, y座標點slice]` | 網格化:返回 x 矩陣、y 矩陣 (稀疏)|
| `argmax(NDA, axis=)` | 最大值的索引 |
| `argmin(NDA, axis=)` | 最小值的索引 |
+ 參數
+ `linspace()`
| 參數 | 說明 |
|------|------|
| `endpoint=True/False` | 是否包含終點 |
| `retstep=True/False` | 是否回傳步進值 |
+ `array()` / `asarray()`
| 參數 | 說明 |
|------|------|
| `object` | 陣列物件 |
| `dtype=None` | 元素資料型別 |
| `copy=True` | 是否深拷貝 |
| `order='K'` | 記憶體儲存方式 |
| `subok=False` | 是否允許子類別繼承 |
| `ndmin=0` | 最小維度 |
+ `sum()`
| 參數 | 說明 |
|------|------|
| `object` | 陣列物件 |
| `axis=1` | 對第幾軸進行操作 |
| `keepdims=True/False` | 保留原有維度 |
> + 原 NDA
> ```
> [[1, 2, 3],
> [4, 5, 6]]
> ```
> + 有 keepdims
> ```
> [[6],
> [15]]
> ```
> + 未 keepdims
> ```
> [6, 15]
> ```
### Math
+ 函數
| 函數 | 說明 |
|------|------|
| `abs(NDA)` | 絕對值 |
| `floor(NDA)` | 向下取整 |
| `ceil(NDA)` | 向上取整 |
| `power(底數NDA, 指數NDA)` | 冪運算 |
| `exp(NDA)` | e 的指數次方 |
| `sqrt(底數NDA)` | 平方根 |
| `log(真數NDA)` | 自然對數 |
| `log10(真數NDA)` | 常用對數 |
| `radians(角度)` | 角度轉弧度 |
| `degrees(弧度)` | 弧度轉角度 |
| `sin()` | 正弦 |
| `cos()` | 餘弦 |
| `tan()` | 正切 |
| `asin()` | 反正弦 |
| `acos()` | 反餘弦 |
| `atan()` | 反正切 |
| `arcsinh()` | 反雙曲正弦 |
| `arccosh()` | 反雙曲餘弦 |
| `arctanh()` | 反雙曲正切 |
### Calculate
+ 函數
| 函數 | 說明 |
|------|------|
| `dot(NDA, NDA)` | 內積(等同 `NDA @ NDA`) |
| `cross(NDA, NDA)` | 外積 |
| `allclose(NDA, NDA, 相對誤差, 絕對誤差)` | 判斷是否大致相等 |
| `average(NDA, axis=, weights=)` | 算術平均或加權平均 |
### Condition
+ 函數
| 函數 | 說明 |
|------|------|
| `count_nonzero(條件)` | 計算符合條件的元素數量 |
| `where(條件, x操作, y操作)` | 無 x、y 操作時回傳滿足條件的 tuple[層索引, 列索引, 行索引];有時執行對應操作並回傳 NDA |
| `clip(NDA, min, max)` | 限制數值範圍 |
### Operation
+ 函數
| 函數 | 說明 |
|------|------|
| `transpose(NDA, axes)` | 轉置 |
| `vstack(NDA, NDA)` | 垂直堆疊 |
| `hstack(NDA, NDA)` | 水平堆疊 |
| `vsplit(NDA, 塊數)` | 垂直分割 |
| `hsplit(NDA, 塊數)` | 水平分割 |
| `append(NDA, NDA, axis=)` | 附加元素(創建新陣列) |
| `repeat(NDA, 重複次數, axis=)` | 重複元素 |
### Setting
+ 函數
| 函數 | 說明 |
|------|------|
| `set_printoptions(參數)` | 更改列印參數 |
+ 參數
+ `set_printoptions()`
| 參數 | 說明 |
|------|------|
| `precision=None` | 小數精確度 |
| `threshold=None` | 元素門檻值(超過則省略中間部分) |
| `edgeitems=None` | 省略時前後顯示的元素數量 |
| `linewidth=None` | 行寬度 |
| `suppress=None` | 抑制顯示小數位 |
| `nanstr=None` | NaN 值顯示字串 |
| `infstr=None` | 無限值顯示字串 |
| `formatter=None` | 自訂格式化函數 |
| `sign=None` | 正負號控制 |
| `floatmode=None` | 浮點數顯示模式 |
## Tips
### Vectorization
+ 單變數
```py
a = np.arange(10)
print(a) # [0 1 2 3 4 5 6 7 8 9]
print(a + 1) # [1 2 3 4 5 6 7 8 9 10]
print(a < 5) # [True True True True True False False False False False]
```
+ 多變數
```py
x = np.linspace(-1, 1, 3)
y = np.linspace(-1, 1, 3)
z = x**2 + y**2
print(x) # [-1. 0. 1.]
print(y) # [-1. 0. 1.]
# | | |
# v v v
print(z) # [ 2. 0. 2.]
```
### Random
```py
# 舊 API (np.random)
np.random.seed(42)
np.random.randn(3, 2) # 正態分佈
np.random.rand(3, 2) # 均勻分佈
# 新 API (Generator)
rng = np.random.default_rng(42)
rng.standard_normal((3, 2)) # 取代 randn()
rng.random((3, 2)) # 取代 rand()
rng.integers(0, 10, (3, 2)) # 取代 randint()
```