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 07

缺值

偵測、刪除、補值,以及補值造成的影響
Interaction實作 30 minute(s)

Learning Objectives

  • 用 isna 找出缺值並數出每一欄缺幾筆,知道 NaN 不能用 == 比較
  • 說出 mean、std 等統計量預設略過缺值,以及 count 與 len 的差別
  • 用 dropna、fillna、ffill、interpolate 處理缺值,並說出補平均對標準差與分布形狀的影響
  • 分辨缺值的原因(隨機或和數值本身有關),說明為什麼原因會讓結果偏誤

資料裡的空格

真實的資料幾乎都有空格:學生缺考、問卷有一題沒填、電表某天沒回報。pandas 把這些空格記成 NaN(Not a Number,缺值,missing value)。 缺值本身不難處理,難的是選哪一種處理方法:每一種方法都會改變平均、標準差或分布的樣子,有時還會讓結論偏掉。

這一課用兩份資料,都是程式產生的模擬資料,不是任何學校的真實資料:

檔案 缺值
grades.csv(600 筆修課成績) 期中考有人缺考
dorm_power.csv(5 棟宿舍 × 122 天的用電) 有幾天電表沒有回報

逐步看:找出缺值、數一數

看 absent 在記憶體區的表格:期中那一欄的值是 NaN。

刪除或補值:每一種都有代價

常見的處理方法:

方法 寫法 代價
不處理(略過缺值) s.mean() 平均、標準差等統計量預設跳過 NaN;但要記得實際用了幾筆(count())
刪除 s.dropna()、df.dropna(subset=[...]) 筆數變少;整列刪除時,那一列其他欄的資料也一起丟掉
補平均、中位數 s.fillna(s.mean()) 補上的值都在正中間:標準差變小,分布多出一根很高的柱子
補一個固定值 s.fillna(0) 把「不知道」寫成一個真的數字;補 0 會把平均拉低

補平均讓平均不變,看起來很安全,但補上的每一筆離平均的距離都是 0,所以資料「看起來」比實際更集中。 之後要算標準差、信賴區間或做檢定時,這會讓你對結果過度有信心。

逐步看:五種方法的平均與標準差

迴圈每一圈處理一種方法,s 是處理後的期中成績。注意最後一行:補平均之後,正好等於平均的值從 0 筆變成 13 筆。

互動練習:補值對平均、標準差與分布的影響

選一份資料和一種處理方法,看點圖上補上的點(綠色)落在哪裡,下方的表比較每一種方法的平均、中位數與標準差。 期中成績是一門 24 人的課,有 6 人缺考(缺值占四分之一,比較容易看出差別);用電是 C 棟 9~12 月每天的用電。

有先後順序的資料:ffill 與 interpolate

每日用電、每小時溫度這種依時間排列的資料,相鄰的值通常很接近,可以用附近的值估計缺值:

  • s.ffill()(forward fill):用前一筆的值補。適合「狀態持續到下次改變」的資料,例如設定值、價格。
  • s.interpolate():用前後兩筆連成直線,取中間的值。適合連續變化的量,例如溫度、用電。

兩種方法都要求資料已經依時間排好;開頭的缺值前面沒有值可以參考,所以補不到。 相對地,期中成績這種沒有先後順序的資料,「前一筆」只是剛好排在旁邊的另一位學生,用 ffill 沒有道理。

逐步看:C 棟用電的三種補法

最後一步會畫出整季的用電與補上的點。紅色的 × 是補整季平均的位置,和前後幾天比一比。

為什麼缺?原因會讓結果偏掉

處理方法之外,更要問資料為什麼缺。統計學常用下面三種情況來描述,其中「隨機遺漏」的概念出自 Rubin(1976):

情況 意思 例子
完全隨機遺漏(MCAR) 缺不缺和任何事都無關 電表隨機故障
隨機遺漏(MAR) 缺不缺和其他已知的欄位有關 某一棟的電表比較舊,比較常沒回報
非隨機遺漏(MNAR) 缺不缺和缺掉的值本身有關 準備不足、可能考低分的人比較常缺考

只有完全隨機遺漏時,略過或刪除缺值才不會讓平均偏掉。如果低分的人比較常缺考,剩下的人本來就比較高分, 不管是略過缺值或補平均,算出來的平均都會偏高;這不是補值方法能修正的。下一個範例用模擬實驗看這件事。

參考:Rubin, D. B. (1976). Inference and missing data. Biometrika, 63(3), 581–592.

逐步看:缺考的原因不同,平均偏差不同

因為是模擬,我們知道每個人「真正」的分數。比較兩種缺考情況下,略過缺值算出的平均和真正的平均差多少。

實作:E 棟的用電缺值

讀入 dorm_power.csv,取出 E 棟(building 是 "E")的用電 kwh,存成 e(資料已經依日期排好)。 用內插補上缺值存成 filled,最後兩行會印出補值前後的缺值數與平均。

你的輸出
預期輸出

小測驗:缺值

1.

下面程式會印出什麼?

import numpy as np
import pandas as pd
s = pd.Series([10, np.nan, 20, np.nan])
print(s.count(), len(s), s.mean())
2.

下面程式會印出什麼?

import numpy as np
import pandas as pd
s = pd.Series([1, np.nan, 3])
print((s == np.nan).sum(), s.isna().sum())
3.

一欄成績有 30% 是缺值,你用平均補上。之後算出的標準差會怎樣?

4.

下面程式會印出什麼?

import numpy as np
import pandas as pd
s = pd.Series([np.nan, 4, np.nan, 8])
print(s.ffill().tolist())
5.

問卷的「每月收入」一題,收入高的人比較常不填。只用有填的人算平均,結果會怎樣?

第 1 次作答

重點整理

  • 缺值是 NaN;找缺值用 isna()(NaN 不等於自己),isna().sum() 數出每一欄缺幾筆。
  • mean、std 等統計量預設略過缺值;count() 是有值的筆數,len() 是長度。
  • dropna() 刪除、fillna() 補值、時間序列用 ffill() 或 interpolate();每一種都有代價,補平均會讓標準差變小、分布變尖。
  • 缺值的原因比處理方法更重要:和缺掉的值本身有關時,任何補法都修正不了偏差。報告裡要寫清楚缺了幾筆、為什麼缺、怎麼處理。
  • 下一課處理另一種髒資料:寫法不一致、型別錯誤、重複的列與超出範圍的值。
這一課完成了!
Next lesson:資料清理
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。