National Central University
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try an AI Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

3

Local AI

--

Uedu Code

--

中央大學 AQI 80 24°C PM2.5 21
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 05

選取資料

欄、列、loc 與 iloc、布林篩選、query
Interaction實作 30 minute(s)

Learning Objectives

  • 用 df["欄"] 與 df[["欄", "欄"]] 選出欄,說出結果是 Series 還是資料表
  • 用 loc(標籤)與 iloc(位置)選出一塊資料,說出兩種切片在結尾的差別
  • 用布林條件篩選列,以 &、|、~ 組合條件,並說出為什麼每個比較要加括號
  • 用 isin 與 query 寫出常見的篩選,知道篩選後的索引不會重新編號

只看需要的那一塊

讀進一份資料表(DataFrame)後,分析幾乎都從「挑出一部分」開始:只看期末成績這一欄、只看微積分的修課紀錄、 只看缺席 5 次以上又不及格的人。挑得對,後面的平均、圖表才有意義。

pandas 有四種常用的挑法:

想做的事 寫法 例子
選欄 df["欄"]、df[["欄", "欄"]] 只看課程與期末
依標籤選列與欄 df.loc[列, 欄] 學號 S03 到 S06 的期中、期末
依位置選列與欄 df.iloc[列, 欄] 第 0~2 列、第 2~3 欄
依條件選列 df[條件]、df.query("條件") 期末不及格的人

這一課用 grades.csv(600 筆修課成績)與 students.csv(200 位學生)。兩份都是程式產生的模擬資料,不是任何學校的真實資料。

逐步看:單層括號與雙層括號

注意右邊記憶體區:final 只有一欄、沒有表頭;two 和 one 是資料表。

loc 看標籤,iloc 看位置

每一列都有一個標籤(索引,index),也有一個位置(從 0 開始數第幾列)。剛讀進來的表,兩者剛好一樣(0、1、2…), 所以初學時很容易混在一起;只要篩選或排序過,兩者就不一樣了。

loc iloc
用什麼找 列標籤、欄名稱 列位置、欄位置(整數,從 0 起算)
切片 a:b 包含 b 不含 b(和串列切片一樣)
例子 df.loc["S02":"S04", "final"] df.iloc[1:3, 0:2]

逗號前面是列、後面是欄;只寫一個就是只選列(欄全部要)。df.loc["S03"] 取出一列,得到的是 Series。

逐步看:loc 與 iloc 選到的範圍

這個小表用學號當列標籤。看最後兩行:同一位學生,在篩選後的表裡位置變了,標籤沒變。

互動練習:欄、loc、iloc 與條件

選一種操作、設定好之後按「執行」:上面的表會標出留下的列與欄,下面出現產生的新表,並顯示對應的 pandas 程式。 條件要自己寫,寫錯時會看到和 pandas 相同類型的錯誤訊息。依序完成下面的任務。

布林篩選:先算出一串 True/False

grades["final"] >= 90 不會只得到一個 True 或 False,而是每一列一個:一串和資料表一樣長的布林值(布林 Series)。 把這一串放進方括號 grades[...],留下的就是 True 的那些列。

兩個條件要用 &(而且)、|(或)連接,前面加 ~ 表示「不是」。每個比較都要加括號:

grades[(grades["course"] == "微積分") & (grades["final"] < 45)]

原因是 Python 的運算子優先順序:&、| 比 >=、== 先算。不加括號時,Python 會先算 "微積分" & grades["final"], pandas 會出現錯誤。也不能用 and、or:它們要把整串布林值變成一個 True 或 False,pandas 不知道該怎麼變,所以會出現 「The truth value of a Series is ambiguous」錯誤。

兩個常用的簡寫:

  • grades["course"].isin(["英文", "經濟學"]):值在清單裡就是 True,比寫好幾個 | 清楚。
  • grades.query("absences >= 5 and final < 60"):把條件寫成一個字串,欄名直接寫、可以用 and、or。

逐步看:篩選 600 筆修課紀錄

看 high 在記憶體區的樣子:它是一串 True/False,長度和資料表一樣。

實作:住宿又認真讀書的學生

讀入 students.csv,選出住宿(dorm 是 "Y")而且每週讀書時數(study_hours)15 小時以上的學生, 只留 student_id、dept、study_hours 三欄,存進 busy。程式最後兩行會印出人數與前 5 列。

你的輸出
預期輸出

小測驗:選取與篩選

1.

下面程式會印出什麼?

import pandas as pd
df = pd.DataFrame({"a": [1, 2], "b": [3, 4]})
print(type(df["a"]).__name__, type(df[["a"]]).__name__)
2.

下面程式會印出什麼?

import pandas as pd
df = pd.DataFrame({"x": [5, 6, 7, 8, 9]}, index=["a", "b", "c", "d", "e"])
print(len(df.loc["b":"d"]), len(df.iloc[1:3]))
3.

df[df["final"] >= 60 & df["dept"] == "資工"] 執行時出現錯誤,該怎麼改?

4.

哪一個和 df.query("absences >= 5 and final < 60") 選出相同的列?

5.

下面程式會印出什麼?

import pandas as pd
s = pd.Series([10, 20, 30, 40])
t = s[s > 15]
print(t.iloc[0], t.loc[3])
第 1 次作答

重點整理

  • df["欄"] 得到 Series(一維),df[["欄", "欄"]] 得到資料表(二維)。
  • loc 用列標籤與欄名稱,切片包含結尾;iloc 用位置(從 0 起算),切片不含結尾。逗號前是列、後是欄。
  • 篩選時先算出一串 True/False,再放進方括號;sum() 可以數出符合的筆數。
  • 條件用 &、|、~ 組合,每個比較加括號;不能用 and、or。isin 與 query 讓常見的條件更好讀。
  • 篩選後的索引沿用原本的標籤,不會重新編號,所以 loc 與 iloc 的結果會不一樣。
  • 下一課學排序(sort_values)與新增計算欄位。
這一課完成了!
Next lesson:排序與新增欄位
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。