# numpy [![RogelioKG/numpy](https://img.shields.io/badge/Sync%20with%20HackMD-grey?logo=markdown)](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() ```