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 08

資料清理

型別轉換、字串處理、重複資料、超出範圍的值
Interaction實作 30 minute(s)

Learning Objectives

  • 用 dtypes、unique、describe、duplicated 找出資料表裡的問題
  • 用 str.strip、str.replace 與對照表統一文字的寫法
  • 把文字欄轉成數字與日期,說出 astype 與 to_numeric(errors="coerce") 的差別,以及日期月日順序的歧義
  • 處理超出範圍的值與重複的列,並說明為什麼不該把錯誤的值改成「看起來合理」的值

人工輸入的資料

上一課處理的是空著的格子;這一課處理填了但填錯的格子。資料由好幾個人手動輸入、從不同系統匯出時,常見這些問題:

問題 例子 後果
同一個值有好幾種寫法 「資工」「資工系」「資訊工程」「 資工」 分組時被當成不同的系
數字欄混了文字 「85分」「 72 」「缺考」 整欄變成文字(object),不能算平均
超出合理範圍 期末 150 分、-5 分 平均與標準差被拉偏
日期寫法不一 2026-11-10、2026/11/08、11/03/2026 不能排序、不能算相隔幾天
重複的列 同一筆紀錄輸入兩次 重複計算

這一課的 grades_raw.csv 是程式產生的模擬資料(63 列),不是任何學校的真實資料,問題是刻意放進去的。 清理的第一步永遠是先看:看型別、看有哪些寫法、看最大最小值。

逐步看:先檢查,再動手

每一行都在找一種問題。注意 unique() 的結果裡,有幾個字串前後多了空白。

統一寫法與轉換型別

文字欄可以用 .str 接上字串的方法,一次處理整欄:

寫法 做什麼
s.str.strip() 去掉前後的空白
s.str.replace("系", "") 把「系」換成空字串(刪掉)
s.replace({"資訊工程": "資工"}) 用對照表把整格的值換掉

數字欄混了文字時,astype(float) 只要遇到一格轉不了就整個失敗;pd.to_numeric(s, errors="coerce") 則把轉不了的格子變成缺值(NaN)。 後者方便,但也會把真正寫錯的值靜靜地變成缺值,所以轉換前先用 unique() 看過有哪些寫法,轉換後再數一數多了幾個缺值。

逐步看:系所與期中

看 dept 在記憶體區的變化:每一步處理一種寫法上的差異。

互動練習:逐項處理 grades_raw.csv

每張卡片是一種問題。選一種處理方法,看下面的表格怎麼變、剩下幾個問題;有些方法會讓問題消失,卻製造新的問題(紅色虛線框)。 表格是 grades_raw.csv 的全部 63 列,預設只顯示有問題或改過的列。依序完成下面的任務。

超出範圍、日期與重複

超出範圍的值:期末 150 分顯然錯了,但「正確的分數」是多少,資料裡沒有答案。把它截成 100(clip)看起來整齊, 其實是編了一個分數;比較誠實的做法是改成缺值(where),並回頭查原始紀錄。刪掉整列也會讓問題消失,但同一列其他欄的資料也一起丟了。

日期:pd.to_datetime 把文字轉成日期型別,之後才能排序、比較、算相隔幾天。寫法不只一種時加 format="mixed",每一格各自判斷。 「11/03/2026」是 11 月 3 日還是 3 月 11 日?美國習慣「月/日/年」,很多國家習慣「日/月/年」;pandas 預設月在前,dayfirst=True 改成日在前。 只看資料本身常常分辨不出來,要問資料是誰、用什麼系統輸入的。

重複的列:duplicated() 標出和前面某一列完全相同的列,drop_duplicates() 刪掉它們。 要注意「完全相同」的意思:系所一個寫「資工」、一個寫「資工系」的兩列不算重複,所以先統一寫法,再找重複。

逐步看:期末、日期與重複的列

看 bad 與 dup:它們都是一串 True/False,用來選出要處理的列。

實作:清理系所與期中

讀入 grades_raw.csv,在 clean 上完成三件事: 1. 系所(dept)去掉前後空白、刪掉「系」字,再把「資訊工程」換成「資工」、「企業管理」換成「企管」; 2. 期中(midterm)去掉前後空白與「分」字,用 pd.to_numeric(..., errors="coerce") 轉成數字; 3. 刪掉重複的列。

最後三行會印出列數、各系筆數與期中平均。

你的輸出
預期輸出

小測驗:資料清理

1.

下面程式執行時會發生什麼?

import pandas as pd
s = pd.Series(["85", "72分", "90"])
print(s.astype(float).tolist())
2.

下面程式會印出什麼?

import pandas as pd
s = pd.Series(["85", "缺考", " 72 "])
print(pd.to_numeric(s, errors="coerce").tolist())
3.

下面程式會印出什麼?

import pandas as pd
df = pd.DataFrame({"id": ["A", "A", "B", "A"], "dept": ["資工", "資工", "資工", "資工系"]})
print(df.duplicated().tolist())
4.

期末成績有一格是 150,你查不到原始紀錄。下面哪一種處理最恰當?

5.

下面程式會印出什麼?

import pandas as pd
d = pd.to_datetime("11/03/2026", dayfirst=True)
print(d.strftime("%Y-%m-%d"))
第 1 次作答

重點整理

  • 清理前先看:dtypes(數字欄是不是 object)、unique()(有哪些寫法)、describe()(最大最小值)、duplicated().sum()。
  • 文字用 .str.strip()、.str.replace() 與對照表 replace({...}) 統一寫法。
  • 轉數字:astype 遇到一格轉不了就失敗;pd.to_numeric(..., errors="coerce") 把轉不了的變成缺值,轉完要數一數多了幾個缺值。
  • 超出範圍的值不要「修」成看起來合理的數字;改成缺值、查原始紀錄,並在報告寫明。
  • 日期用 pd.to_datetime,寫法不一時加 format="mixed";斜線寫法的月日順序要確認資料來源。
  • 先統一寫法,再用 drop_duplicates() 刪重複的列。
  • 下一課用乾淨的資料做分組彙總:各系、各課程的平均是多少。
這一課完成了!
Next lesson:分組彙總
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。