① 依序閱讀:每節先讀說明;遇到互動元件時,先預測結果,再操作驗證。 ② 對照程式範例:程式碼卡下方的「來源」標了課程練習筆記本(lab);需要實作時,再打開原始筆記本對照。 ③ 檢查理解:答錯時先看回饋,再回到相關說明;標為延伸的內容可留待第二輪。 ④ 最後翻關鍵詞彙卡自測術語,並用 重點速查與來源查閱。
教科書:An Introduction to Statistical Learning with Applications in Python(ISLP)。章節旁的來源標記可點到本頁書目。
pandas 用標籤管理資料,讓你可以依欄名「mpg」取值,也可以指定「第 3 欄」這類位置。 一維資料稱為 Series,二維資料表稱為 DataFrame。
dtypes 是逐欄的:state 是 object、year 是 int64、pop 是 float64。這一點跟 NumPy 陣列不同——陣列整塊只能有一個型別。
d 4 b 7 a -5 c 3 dtype: int64
左邊那一排 d b a c 是索引,不是資料。
Ch01-lab-zh.ipynb
state year pop 0 Ohio 2000 1.5 1 Ohio 2001 1.7 2 Ohio 2002 3.6 3 Nevada 2001 2.4 4 Nevada 2002 2.9 5 Nevada 2003 3.2
鍵變成欄名,值變成那一欄的內容。列索引沒指定時就是 0、1、2…
來源:Ch01-lab-zh.ipynb
frame['pop'] 拿到的是什麼?
拿到一份沒看過的資料,前五分鐘不要急著建模。先跑這四行:
shape 看有多大、head() 看長什麼樣、
describe() 看數值範圍合不合理、dtypes 看有沒有欄被讀成字串。
第四項最常出事,下一節會看到。
shape 再 dtypes——型別會影響 describe() 彙總哪些欄位,先核對型別再讀摘要。
A B C D
2025-09-01 -0.397297 -1.061537 1.455216 0.632237
2025-09-02 -0.840037 -1.592677 -0.604842 -1.500806
2025-09-03 0.501820 -0.662466 0.146713 0.293567
2025-09-04 -1.060077 -1.010073 0.553983 0.211157
2025-09-05 -0.109702 0.236859 -0.203407 0.695861
A B C D
2025-09-04 -1.060077 -1.010073 0.553983 0.211157
2025-09-05 -0.109702 0.236859 -0.203407 0.695861
2025-09-06 0.157943 -0.966041 0.844384 1.641228head() 預設五列,tail(3) 給最後三列。
Ch01-lab-zh.ipynb
A B C D count 6.000000 6.000000 6.000000 6.000000 mean -0.291225 -0.842656 0.365341 0.328874 std 0.594509 0.608525 0.743696 1.030710 min -1.060077 -1.592677 -0.604842 -1.500806 25% -0.729352 -1.048671 -0.115877 0.231760 50% -0.253499 -0.988057 0.350348 0.462902 75% 0.091032 -0.738359 0.771784 0.679955 max 0.501820 0.236859 1.455216 1.641228
count 那一列很有用。它不算遺漏值,所以某一欄的 count 比別欄少,就代表那欄有 NaN。
Ch01-lab-zh.ipynb
describe() 為什麼漏掉某些欄?describe(include='all') 可以連類別欄一起看。count 跟 len(df) 差在哪?len(df) 是列數,count 是非遺漏的個數。兩個數字不一樣,就代表那一欄有 NaN。這可以用來檢查遺漏值。sort_index 排列列/欄的標籤;sort_values 按指定欄的數值排列資料列。
axis=1 指欄方向,ascending=False 指遞減順序。排序後標籤仍跟著原本的資料走。
D C B A
2025-09-01 0.632237 1.455216 -1.061537 -0.397297
2025-09-02 -1.500806 -0.604842 -1.592677 -0.840037
2025-09-03 0.293567 0.146713 -0.662466 0.501820
2025-09-04 0.211157 0.553983 -1.010073 -1.060077
2025-09-05 0.695861 -0.203407 0.236859 -0.109702
2025-09-06 1.641228 0.844384 -0.966041 0.157943
A B C D
2025-09-02 -0.840037 -1.592677 -0.604842 -1.500806
2025-09-01 -0.397297 -1.061537 1.455216 0.632237
2025-09-04 -1.060077 -1.010073 0.553983 0.211157
2025-09-06 0.157943 -0.966041 0.844384 1.641228
2025-09-03 0.501820 -0.662466 0.146713 0.293567
2025-09-05 -0.109702 0.236859 -0.203407 0.695861Ch01-lab-zh.ipynb
mean() 預設沿列計算各欄平均;DataFrame 相加會先對齊列與欄標籤,再逐元素相加。
apply(np.cumsum) 在這個數值表上逐欄累積加總,因此每一列表示從開頭累積到該列的總量。
A -0.291225
B -0.842656
C 0.365341
D 0.328874
dtype: float64
A B C D
2025-09-01 -0.794593 -2.123075 2.910432 1.264474
2025-09-02 -1.680074 -3.185354 -1.209683 -3.001613
2025-09-03 1.003641 -1.324931 0.293426 0.587134
2025-09-04 -2.120153 -2.020146 1.107965 0.422315
2025-09-05 -0.219403 0.473718 -0.406813 1.391721
2025-09-06 0.315886 -1.932082 1.688768 3.282456
A B C D
2025-09-01 -0.397297 -1.061537 1.455216 0.632237
2025-09-02 -1.237333 -2.654214 0.850374 -0.868569
2025-09-03 -0.735513 -3.316680 0.997087 -0.575002
2025-09-04 -1.795590 -4.326753 1.551070 -0.363845
2025-09-05 -1.905291 -4.089894 1.347664 0.332016
2025-09-06 -1.747348 -5.055935 2.192048 1.973244Ch01-lab-zh.ipynb
read_csv、read_excel 將檔案讀為資料表;to_csv、to_excel
將目前的表輸出到檔案。下列兩個命令會在執行目錄建立檔案,檔名已存在時會覆寫;預設也會寫出列索引。
只想保留資料欄時可指定 index=False。Excel 讀寫另需要相容的引擎,例如 openpyxl。
這兩個命令的結果是檔案;lab未保存文字輸出。
來源:Ch01-lab-zh.ipynb
loc 靠名字、iloc 靠位置 課程 Lab Ch1 · lab 範例pandas 的兩套選取語法使用不同的依據:
loc 靠名字、iloc 靠位置。
選取之前,先確認要用標籤還是位置。
loc 的切片包含結尾,iloc 不包含。df.loc['a':'c'] 會拿到 c,df.iloc[0:3] 只拿到 0、1、2。因為名字沒有「下一個」可言,含頭不含尾對它沒有意義。
df['A'] 取的是欄,但 df[0:3] 取的是列——同一個中括號,兩種意思。這就是為什麼建議一律用 loc/iloc 寫清楚。
2025-09-01 -0.397297
2025-09-02 -0.840037
2025-09-03 0.501820
2025-09-04 -1.060077
2025-09-05 -0.109702
2025-09-06 0.157943
Freq: D, Name: A, dtype: float64
A B C D
2025-09-01 -0.397297 -1.061537 1.455216 0.632237
2025-09-02 -0.840037 -1.592677 -0.604842 -1.500806
2025-09-03 0.501820 -0.662466 0.146713 0.293567注意兩者的差別:df['A'] 給 Series,df[0:3] 給 DataFrame。
Ch01-lab-zh.ipynb
A C 2025-09-01 -0.397297 1.455216 2025-09-02 -0.840037 -0.604842 2025-09-03 0.501820 0.146713 2025-09-04 -1.060077 0.553983 2025-09-05 -0.109702 -0.203407 2025-09-06 0.157943 0.844384 A -1.060077 B -1.010073 C 0.553983 D 0.211157 Name: 2025-09-04 00:00:00, dtype: float64
df.iloc[3] 拿一整列,回來的是 Series——那一列的欄名變成了它的索引。
Ch01-lab-zh.ipynb
A B C D 2025-09-03 0.501820 -0.662466 0.146713 0.293567 2025-09-06 0.157943 -0.966041 0.844384 1.641228
裡面的 df['A'] > 0 就是 P3 講的布林遮罩,只是現在它帶著索引。
Ch01-lab-zh.ipynb
df.loc['b':'d'] 與 df.iloc[1:3],哪一個的敘述正確?
set_index('name') 將 name 欄用作列標籤,預設從一般資料欄移除它。
這只改變如何查找列,不會把車名變成唯一識別碼:同一名稱仍可能出現多次。
mpg origin name ford galaxie 500 15.0 1 ford galaxie 500 14.0 1 ford galaxie 500 14.0 1
Ch02-statlearn-lab-zh.ipynb
loc 使用標籤,回傳一列或多列取決於標籤是否重複與索引寫法。
iloc 仍依位置取資料。需要回到一般欄位時使用 reset_index()。
課程 lab 讀進 Auto 之後,
horsepower 那一欄整欄是字串,因為原始檔用 ?
代表遺漏,pandas 看到問號就把整欄當成文字。這種錯誤不會報錯,只會讓你後面算出來的東西全錯。
? → 在讀檔時就宣告它是遺漏 → 決定要不要 dropna。
replace 再 astype(float),很容易漏掉某些欄。na_values=['?'] 一次解決,而且下次重跑也不會忘。
全部是帶引號的字串,輸出末尾就會看到那個 '?'。整欄因此被讀成 object。
Ch02-statlearn-lab-zh.ipynb
np.float64(40952.0)
加上 na_values=['?'] 之後,sum() 才算得出數字。那個 np.float64 就是證據。
Ch02-statlearn-lab-zh.ipynb
(397, 9) (392, 9)
整門課後面用的 Auto 都是這 392 筆。你在課本裡看到的 n=392 就是從這裡來的。
Ch02-statlearn-lab-zh.ipynb
a -5.3 b 7.2 c 3.6 d 4.5 e NaN dtype: float64
索引裡多了一個 e,原本沒有這一筆,pandas 就填 NaN。遺漏值不是只有讀檔會產生。
Ch01-lab-zh.ipynb
| 做法 | 什麼時候用 | 風險 |
|---|---|---|
na_values=[…](讀檔時) | 原始檔用特殊符號表示遺漏 | 幾乎沒有,應該是預設動作 |
dropna() | 遺漏很少、而且看起來是隨機遺漏 | 遺漏不是隨機時會產生偏差 |
fillna(中位數) | 想保留樣本數 | 低估變異、稀釋相關性 |
| 當成一個類別(遺漏指示變數) | 「有沒有填」本身可能幫助預測 | 不能單靠指示變數修正非隨機遺漏的偏差 |
Auto['horsepower'].mean() 在沒有加 na_values=['?'] 的情況下會發生什麼?
cylinders 是汽缸數。它以整數儲存,但在比較不同汽缸數的車時,也可以視為類別。
轉為 category 後,各個值成為群組水準,適合畫各組分布或建立類別編碼。
CategoricalDtype(categories=[3, 4, 5, 6, 8], ordered=None, categories_dtype=int64)
Ch02-statlearn-lab-zh.ipynb
型態轉換不會決定研究問題;是否把汽缸數當連續效應、順序效果或類別效果,仍須依模型與問題選擇。 不要因為類別代碼是 0、1、2,就自動把代碼間距當成測量距離。
groupby 用來分組彙總,可以分成三個步驟:
拆分(照某一欄的值把列分堆)→ 套用(每一堆各算一次)→
合併(把結果疊回一張表)。看懂這三步,所有變形都是同一件事。
sum(numeric_only=True) 明講「只算數值欄」,若未限定欄位,字串也可能被加總成串接結果,而且不一定會警告。
A foo 5 bar 3 Name: count, dtype: int64
value_counts() 是拿到類別欄的第一個動作。某一類只有兩三筆的話,後面做分類會很吃力。
Ch01-lab-zh.ipynb
C D A bar 1.747047 2.499340 foo -2.740490 0.700964
A 從一般的欄變成了索引,所以輸出裡它單獨一行、下面是 bar 與 foo。
Ch01-lab-zh.ipynb
df.groupby('A').sum() 之後,欄 A 跑去哪了?
這節整理串接與讀檔的用法。上一節的 ? 影響欄位型別,提醒我們
讀檔時先確認分隔符與遺漏值設定。
([ A B C D
2025-09-01 -0.397297 -1.061537 1.455216 0.632237
2025-09-02 -0.840037 -1.592677 -0.604842 -1.500806,
A B C D
2025-09-03 0.501820 -0.662466 0.146713 0.293567
2025-09-04 -1.060077 -1.010073 0.553983 0.211157,
A B C D
2025-09-05 -0.109702 0.236859 -0.203407 0.695861
2025-09-06 0.157943 -0.966041 0.844384 1.641228],
pandas.core.frame.DataFrame)切片給的是三個 DataFrame,裝在一個串列裡。
來源:Ch01-lab-zh.ipynb
A B C D 2025-09-01 -0.397297 -1.061537 1.455216 0.632237 2025-09-02 -0.840037 -1.592677 -0.604842 -1.500806 2025-09-03 0.501820 -0.662466 0.146713 0.293567 2025-09-04 -1.060077 -1.010073 0.553983 0.211157 2025-09-05 -0.109702 0.236859 -0.203407 0.695861 2025-09-06 0.157943 -0.966041 0.844384 1.641228
接回去之後跟原本一模一樣。注意註解裡那句話:加一欄很快,加一列要複製整張表——所以不要在迴圈裡一列一列 append。
來源:Ch01-lab-zh.ipynb
np.float64(40952.0)
sep=r"\s+" 是「一個以上的空白當分隔」,na_values 是「這些字算遺漏」。讀檔時先寫清楚規則,之後較容易核對資料。
Ch02-statlearn-lab-zh.ipynb
concat 沿著列把它們接起來。
concat 跟 merge 差在哪?concat 是疊:形狀相容就沿著某個軸接起來,預設沿列(axis=0)。merge 是對:照某個鍵把兩張表配對,像 SQL 的 join。本課的 lab 主要用 concat,但實務上 merge 更常見。pd.concat(串列) 一次接完。回顧本頁觀念與原 Lab 的程式,確認各個操作的意義與使用條件。
df 的索引是日期。想拿「第 3 到第 5 列」,正確的寫法是?
想得到「每個 origin 的平均 mpg」,而且結果要是一張有 origin 欄的普通表,怎麼寫?
需要核對完整公式、比較表或實作時,再展開下方速查。
三張速查表整理選取語法、資料檢查與分組彙總。
| 你想做的事 | 寫法 | 拿到什麼 |
|---|---|---|
| 取一欄 | df['A'] | Series |
| 取一欄但要 DataFrame | df[['A']] | DataFrame(一欄) |
| 取幾欄 | df.loc[:, ['A','C']] | DataFrame |
| 取一列(照位置) | df.iloc[3] | Series(欄名變索引) |
| 取幾列(照位置) | df.iloc[1:4] | DataFrame,不含第 4 |
| 取幾列(照名字) | df.loc['a':'c'] | DataFrame,含 c |
| 用條件選列 | df[df['A'] > 0] | DataFrame |
| 某一格 | df.loc['a', 'A'] | 純量 |
| 拿到新資料的前五分鐘 | 看什麼 |
|---|---|
df.shape | 列數欄數跟預期一樣嗎 |
df.head() | 欄名對嗎、有沒有整欄空白 |
df.dtypes | 該是數字的欄有沒有變成 object |
df.describe() | 範圍合理嗎;count 比列數少就是有 NaN |
df['類別欄'].value_counts() | 有沒有哪一類只有兩三筆 |
| groupby 的三個動作 | 發生什麼 |
|---|---|
| 拆分(split) | 照鍵的值把列分成幾堆 |
| 套用(apply) | 每一堆各算一次彙總函式 |
| 合併(combine) | 把結果疊成一張表,鍵變成索引 |
dtypes。該是數字的欄變成 object,代表原始檔裡有非數字的東西(例如 Auto 的 ?)。loc 靠名字、iloc 靠位置;loc 的切片含尾。as_index=False 或 reset_index()。
詞彙卡整理本頁引用的課程 lab中常用的統計或機器學習專有名詞,正面附英文名稱。 先看正面的術語,試著說出定義,再翻面核對。可以洗牌複習,也可以搭配本章例子練習解釋。