跳到主要內容

Day 15 NumPy 入門

Day 15 NumPy 入門

引言

Python 內建的串列很靈活,但當資料量變大、想做數值運算時,速度與便利性都不夠。NumPy 是 Python 資料科學的基石,它的核心是 ndarray(N-dimensional array,多維陣列),可以用來表示向量、矩陣、甚至更高維度的資料。相較於純 Python 串列,NumPy 陣列在記憶體配置上更連續,運算速度往往快上幾十倍甚至上百倍,這在處理影像、訊號、機器學習特徵時特別明顯。從這個章節開始,你的程式碼會越來越像在做數學運算,而不是在處理「一堆容器」了。

從今天起,我們正式進入資料處理的章節。先把 NumPy 的基礎打穩,後面 Pandas 的 DataFrame 內部其實就是用 NumPy 陣列儲存資料,再後面 PyTorch 的張量(Tensor)設計也深受 NumPy 影響。今天會學會安裝、建立陣列、認識 shape 與 dtype,並做最基本的運算。學完之後,你會對「為什麼資料科學幾乎離不開它」有具體感受,也能在自己的腳本裡取代一些低效的 Python 迴圈。

安裝與匯入 NumPy

NumPy 並不在 Python 標準庫裡,需要透過 pip 安裝。目前主流的穩定版本是 2.1.x(2024 年中發布),2.0 起對 dtype 與字串處理做了不少重整,如果你從 1.x 升級上來,可能會看到一些 deprecation 訊息。建議搭配 venv 為資料科學專案建立乾淨環境,並把版本固定在 requirements.txt 裡,這樣未來升級時能事先看到警告,不會默默壞掉。如果是在 Windows 上安裝,pip 會自動抓預先編譯的 wheel 套件,多數情況下不需要額外的 C 編譯工具。

pip install numpy==2.1.3

安裝完成後,慣例上用 import numpy as np 匯入,並用 np 當作別名,這是整個資料科學社群共同的命名習慣,讀別人的程式碼也會看到。np 這個短短的別名讓後續寫程式時可以少打很多字,也讓公式化的運算(例如 np.dot(A, B))看起來更像數學表達式。即使到了 PyTorch 章節,你也會看到 import torch 之後,許多公式寫法跟 NumPy 幾乎一樣,這是 NumPy 在資料科學領域影響深遠的證明。

import numpy as np

print(np.__version__)  # 輸出:2.1.3
print(np.array([1, 2, 3]))  # 輸出:[1 2 3]

建立 ndarray:array、zeros、ones、arange、linspace

建立 NumPy 陣列有很多方式,最直接的是把 Python 串列丟給 np.array()。也可以用 zeros() 與 ones() 快速建立全 0 或全 1 的陣列,用 arange() 產生等差數列,用 linspace() 在指定區間切成等距點。理解這些基本建構子,能讓我們在寫機器學習實驗時快速準備測試資料,例如快速生成一組 0 到 1 的特徵當作輸入,或用 zeros 建立模型的初始權重。

import numpy as np

a = np.array([1, 2, 3, 4])              # 從串列建立
b = np.zeros((2, 3))                    # 2x3 全 0
c = np.ones((3, 2))                     # 3x2 全 1
d = np.arange(0, 10, 2)                 # 等差:0,2,4,6,8
e = np.linspace(0, 1, 5)                # 0~1 切 5 點:[0, 0.25, 0.5, 0.75, 1]
f = np.random.default_rng(42).normal(0, 1, (2, 3))  # 2x3 常態分配亂數

print(a)
print(b)
print(e)

np.array() 會根據傳入的資料自動推斷 dtype,如果串列裡有整數就會是 int64,如果有浮點數就會是 float64。對於深度學習來說,float32 已經足夠訓練,因此稍後我們會學怎麼指定 dtype。np.random.default_rng() 是 NumPy 1.17 之後推薦的新式亂數 API,可以指定種子讓結果可重現。在做機器學習實驗時,固定亂數種子非常重要,否則每次跑出來的結果都會不一樣,重現實驗會很痛苦。建議每寫一份新的腳本就把 seed 設成一個固定數字(例如 42),這已經是資料科學家之間的笑話。固定 seed 之後,隨機梯度下降、資料切分都會得到相同的結果,之後寫報告也比較方便附上實驗數據。

陣列屬性:shape、dtype、ndim、size

理解陣列的「形狀」與「型別」是寫 NumPy 的基本功。陣列有幾個常用屬性:shape 回傳各維度的大小(tuple)、dtype 是元素的資料型別、ndim 是維度數量、size 是元素的總數。這些屬性幫助我們在除錯時一眼看出陣列結構是否符合預期,例如模型期待的輸入 shape 是 (N, 3, 32, 32),拿到資料後先 print shape 是基本動作。在神經網路裡,輸入通常是 (批次大小, 通道, 高度, 寬度) 這種四維張量,形狀對不上往往是錯誤的根源。熟悉這些屬性之後,再看到別人程式碼裡的 (B, C, H, W) 這種 shape 標記,也能很快理解它的意思。

import numpy as np

x = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float32)
print(x.shape)    # 輸出:(2, 3)
print(x.dtype)    # 輸出:float32
print(x.ndim)     # 輸出:2
print(x.size)     # 輸出:6
print(x.itemsize) # 輸出:4(每個元素佔 4 bytes)

print(x.reshape(3, 2))
print(x.astype(np.int32))

reshape() 可以改變陣列的形狀,但總元素數必須相同。astype() 可以轉換 dtype,常用在「把讀進來的 int 轉成 float32」或「把計算結果轉成 int 儲存」等情境。注意 reshape 回傳新陣列,必要時搭配 x = x.reshape(...) 才會覆蓋原變數。從 2.0 版起,NumPy 對字串 dtype 做了不少改動,如果你的程式要處理中文字串,建議先看一下官方升級指南,避免升級後出現不相容的錯誤。除了 reshape,也可以用 x.T 取得轉置矩陣,用 np.transpose() 進行更一般化的軸對調,這些是矩陣運算的基礎工具。日後做影像或訊號處理時,這些操作會反覆出現。

陣列與純量運算:逐元素計算

NumPy 最直觀的強項是「逐元素運算」。對陣列做加減乘除,會自動套用到每一個元素,這種寫法在純 Python 需要寫 for 迴圈才能完成,不僅囉嗦也比較慢。底層的祕密是 NumPy 透過 C 語言實作的 ufunc(通用函式),迴圈在 C 裡執行,比 Python 的直譯式迴圈快上一個數量級。即使只是百萬級的資料,純 Python 與 NumPy 之間的差距往往就是「一秒鐘 vs 五分鐘」這種天差地別的體驗。

import numpy as np

a = np.array([1, 2, 3, 4])
b = np.array([10, 20, 30, 40])

print(a + 1)       # 輸出:[2 3 4 5]
print(a * 2)       # 輸出:[2 4 6 8]
print(a ** 2)      # 輸出:[1 4 9 16]
print(a + b)       # 輸出:[11 22 33 44]
print(a * b)       # 輸出:[10 40 90 160]

# 套用數學函式
print(np.sin(a))   # 輸出:[0.8415 0.9093 0.1411 -0.7568]
print(np.sqrt(a))  # 輸出:[1. 1.4142 1.7321 2.]

所有 NumPy 提供的「通用函式」(ufunc,例如 np.sin、np.sqrt、np.log)也都是逐元素計算,並且底層用 C 實作,速度非常快。理解這點之後,許多本來需要寫迴圈的數值計算,都能改寫成簡潔的陣列運算式。常見的「向量化」(vectorization)指的就是這種寫法:把整個陣列當成單一運算目標,讓 NumPy 幫我們處理迴圈。日後不論是機器學習特徵工程或訊號處理,都會大量仰賴這個觀念。常用的 ufunc 還包括 np.exp(指數)、np.log(自然對數)、np.round(四捨五入)等,搭配之後做 softmax、機率運算都會非常方便。如果你寫過機器學習的程式,應該會很熟悉「把整個 batch 一次送進去算」這種寫法,那就是向量的精神。

結語

今天把 NumPy 的基礎打好了。我們學會安裝、建立 ndarray、認識 shape 與 dtype,並用逐元素運算處理整個陣列。這些觀念看起來樸素,卻是後續深度學習的根基,因為神經網路的權重、輸入、輸出全都是 ndarray 或更進階的張量。建議裝好 NumPy 並實際跑過今天的範例,特別是 np.random.default_rng 那段,把亂數種子玩熟,之後做實驗會用得上。也可以自己試試把 NumPy 陣列與 Python 串列的運算做個簡單的速度比較,會對「為什麼大家都說 NumPy 快」有更具體的感受。

明天,我們會繼續 NumPy,學習更強大的索引技巧、廣播機制,以及常用的統計函式,這些都是處理資料時天天會用到的工具,會大幅提升你寫資料處理程式的效率。

留言

這個網誌中的熱門文章

Day 2 變數與資料型別

Day 2 變數與資料型別 引言 寫程式的過程中,變數與資料型別是處理資料的基礎。變數是存放資料的容器,資料型別則決定這筆資料有哪些特性、可以進行哪些操作。學會定義變數、認識各種資料型別,是學好 Python 的關鍵一步。 這篇文章會帶你了解 Python 中變數的觀念、如何定義變數,以及常見的資料型別,包括整數、浮點數、字串、布林值,還有串列、元組、字典與集合等容器型別。我們也會介紹變數的命名規則與撰寫風格建議,以及如何用 type() 檢查資料型別。 什麼是變數?如何在 Python 中定義變數 變數是在程式執行時用來存放資料的名稱。透過定義變數,我們可以給一筆資料一個名字,並在程式的其他地方用這個名字取用該筆資料。在 Python 中,變數不需要事先宣告型別,因為 Python 是動態型別語言,變數的型別由指定給它的值決定。 定義變數的基本語法 在 Python 中定義變數非常簡單,只要用賦值符號 = 把值指定給變數即可。例如: x = 5 # 定義變數 x,並把整數 5 賦值給它 name = "Alice" # 定義變數 name,並把字串 "Alice" 賦值給它 在這裡,x 是一個變數,被賦予整數 5;name 是另一個變數,被賦予字串 "Alice"。 變數的更新與覆寫 變數的值可以修改,也就是說,我們可以在程式的不同地方給同一個變數新的值。例如: x = 10 # x 最初被賦予 10 x = 15 # x 的值現在被更新為 15 這樣就能依照需求,在程式執行過程中靈活調整變數的值。 Python 的動態型別系統 Python 和某些靜態型別語言不同,定義變數時不需要宣告型別。賦值時,Python 會根據值自動判斷變數的型別。例如: x = 5 # x 是整數 x = 3.14 # x 變成浮點數 x = "Hi" # x 變成字串 同一個變數在程式執行過程中可以存放不同型別的值,這是 Python 的彈性之一。 常見資料型別 在 Python 中,資料型別決定我們可以對變數進行哪些操作...

Day 1 Python 簡介與環境設定

Day 1 Python 簡介與環境設定 引言 在現在的科技環境裡,程式設計已經是一項重要技能。無論你是對資料科學有興趣、想成為開發者,或是想踏入人工智慧(AI)領域,學會寫程式都能明顯提升你的競爭力。在眾多程式語言中,Python 因為語法簡單、功能強大、應用範圍廣泛,成為許多人進入程式世界的第一選擇。這篇文章會帶你認識 Python 的背景與優勢,並一步步教你在不同系統上安裝與設定 Python 開發環境,最後寫出第一支 Python 程式。 為什麼選擇 Python? Python 是一種高階程式語言,由 Guido van Rossum 在 1991 年發布。Python 的設計哲學強調程式碼的可讀性,並用縮排來定義程式區塊,這點和許多使用大括號的語言不同。簡潔的語法讓它成為初學者的理想選擇;就算是經驗豐富的開發者,也能用它完成複雜的專案。 Python 的優勢如下: 簡單易學 :Python 的語法清楚、結構簡潔,初學者很快就能上手。和其他語言相比,學習曲線相對平緩,不需要先弄懂一堆複雜觀念,就能開始寫程式。 應用範圍廣泛 :從資料科學、網頁開發、人工智慧、機器學習、自動化測試到網路爬蟲,Python 都有大量開源函式庫與工具支援,而且在這些領域都扮演關鍵角色。 豐富的函式庫與框架 :Python 的函式庫生態系非常龐大。做資料分析有 NumPy、Pandas;開發網站有 Django、Flask;做深度學習有 TensorFlow、PyTorch。各種需求幾乎都能找到對應的套件,讓開發更有效率。 跨平台支援 :Python 支援 Windows、macOS、Linux 等作業系統,程式通常不需要太多修改就能跨平台執行,讓開發與部署更有彈性。 活躍的社群 :Python 擁有龐大的開發者社群。學習或開發上遇到問題,幾乎都能在社群與論壇(例如 Stack Overflow)找到答案,對初學者來說是很強的後盾,也能減少卡關時的挫折感。 Python 的應用領域 Python 的流行與強大功能,讓許多領域都開始大量使用它。以下是幾個常見的應用方向: 資料科學 :隨著大數據與人工智慧興起,資料科學大量使用 Python。NumPy、Pandas 與 Matplotlib 等工具能處理和分析龐...

Python 從入門到 PyTorch 深度學習:開啟 AI 世界的大門

Python 從入門到 PyTorch 深度學習:開啟 AI 世界的大門 隨著人工智慧(AI)與深度學習(Deep Learning)快速發展,越來越多人對這些技術產生興趣。不論你是想踏入 AI 領域的初學者,還是已經有程式基礎的開發者,學好 Python 與深度學習框架(例如 PyTorch),都能為你打開更多可能。 為什麼選擇 Python? Python 已經是資料科學與人工智慧領域的首選語言。它的語法簡潔、容易上手,而且擁有龐大的生態系與大量開源函式庫。無論是資料處理、資料視覺化,還是建立機器學習與深度學習模型,Python 都能勝任。對想進入 AI 或資料科學領域的人來說,它幾乎是必備工具。 PyTorch 是什麼? PyTorch 是由 Meta(原 Facebook)AI 研究團隊開發的開源深度學習框架,以易用、靈活和動態計算圖著稱,是許多 AI 研究人員與開發者的首選。相較於其他框架,PyTorch 的寫法更貼近原生 Python,對初學者相對友善。無論是簡單的實驗,還是複雜的深度學習模型,PyTorch 都能提供強大的支援。 這個系列能帶給你什麼? 這個系列會從 Python 的基礎開始,帶你一步一步學習,最後能自己用 PyTorch 建立深度學習模型。即使你完全沒有寫過程式,也能跟著文章的節奏累積技能,理解 AI 與深度學習的核心觀念。 本系列涵蓋的主題 Python 基礎:從變數、條件判斷到函式與模組。 資料處理工具:用 NumPy 與 Pandas 有效率地操作資料。 資料視覺化:用 Matplotlib 與 Seaborn 把資料畫成圖表。 深度學習的數學基礎:線性代數、微積分與機率。 PyTorch 入門:理解張量、模型建構與 GPU 加速。 基礎深度學習模型:CNN 與 RNN 的實作應用。 深度學習專案實戰:從資料前處理到模型部署的端到端流程。 誰適合這個系列? 程式初學者 :如果你對 AI 充滿好奇,卻還沒寫過程式,系列的第一部分會帶你快速上手 Python,並幫助你理解深度學習的基本觀念。 資料科學愛好者 :如果你已經熟悉一些資料處理方法,進階部分會教你如何用 PyTorch 建構深度學習模型。 開發者與研究人員 :想更深入了...