iPAS AI 應用規劃師 中級 科目二 大數據處理分析與應用

pandas 讀 CSV 後 Year 欄位為什麼變成 float64?

原題 43

一間遊戲市場研究公司正在分析全球電子遊戲銷售情況,並準備建立一份「熱銷遊戲銷售報告」。分析師取得了一份名為 vgsales.csv 的資料集,內容包含全球銷量超過 10 萬份的電子遊戲清單。研究團隊希望透過這份資料,了解不同年份、平台與地區的銷售趨勢。 分析師在載入資料後,檢視 Year 欄位的資料型態,發現它是 float64,而非一般年份常用的整數。他想了解這樣的情形為什麼會發生。請問下列哪些原因可能導致這種狀況? 原因 A:CSV 檔中 Year 欄位有缺失值(NaN),導致 Pandas 自動將整欄轉為浮點數。 原因 B:CSV 檔中的年份資料原本是字串(如 "2006"),Pandas 轉換時出錯而變成浮點數。 原因 C:Pandas 預設會將所有數值型態讀取為 float64,不論資料是否為整數。 原因 D:CSV 檔中的年份資料可能包含小數點(例如 2006.0),因此被視為浮點數。

白話

分析師用 pandas 讀 vgsales.csv 後,發現 Year 欄位的資料型別(dtype)是 float64,不是預期的整數 int。題目把四個可能的成因(A 到 D)打包成四個組合選項,要你找出哪些原因確實可能造成這種情形。

問你:哪些原因真的可能導致 pandas 把 Year 欄位讀成 float64?

點選你的答案。

01 總結

一句話總結

正確答案是 選項 B(原因 A 和原因 D):CSV 有缺失值(NaN)時 pandas 自動升成 float64,以及年份資料本身寫成小數點格式(2006.0)時也會讀成 float64。原因 B(字串轉錯)和原因 C(pandas 全預設 float64)都不符合 pandas 的實際行為。

02 情境

先感受問題:年份欄位明明是整數,為什麼被讀成小數?

遊戲研究公司的分析師小凱載入了 vgsales.csv,檢查資料型別:

data.dtypes 輸出:
Name object
Platform object
Year float64 ← 為什麼不是 int64?
Genre object
Global_Sales float64

Year 欄位只有年份(2006, 2010, 2014...),理論上應該是整數。小凱知道這背後有原因,需要找出是哪些情況造成的。

關鍵是理解 pandas 的類型推斷規則:
- 整數欄位一旦混入 NaN,numpy 的 int64 無法表示 NaN,pandas 就自動把整欄升成 float64(因為 Python float 可以用 nan 表示缺失值)。
- CSV 中本身就寫 2006.0(帶小數點)時,pandas 自然讀成 float64。
這兩個原因(A 和 D)是真實成因;原因 B 和 C 是常見誤解。

03 對照

逐一拆解四個原因是否成立

  1. 原因 A:有缺失值(NaN)→ 成立。numpy 的 int64 本來就無法存放 NaN(NaN 是浮點數概念),所以當 pandas 讀到一欄整數資料但其中有缺失值時,它必須把整欄型別提升(upcast)成 float64,才能同時存放整數值和 NaN。這是 pandas 在 Int64(可空整數)推出之前的標準行為。
  2. 原因 B:字串自動轉錯 → 不成立。pandas 讀 CSV 時,如果一欄全是像 "2006" 這樣的數字字串,pd.read_csv 預設會自動嘗試轉型成整數或浮點數,不會因為「原本是字串」就「出錯變成浮點數」。字串純數字能轉換成功,通常會被讀成 int64,而不是 float64。這不是 pandas 的正常行為。
  3. 原因 C:pandas 預設全部讀成 float64 → 不成立。pandas 不會把所有數值都讀成 float64,它會根據內容推斷型別:純整數欄位會被推斷為 int64,有浮點數的欄位才是 float64。「預設全部 float64」這個說法不符合事實。
  4. 原因 D:CSV 本身寫 2006.0 → 成立。如果 CSV 中年份欄位的值是 2006.0(帶小數點),pandas 的類型推斷器看到小數點就會把它讀成 float64,這是完全合理的解析行為。Excel 或舊資料系統匯出的 CSV 有時會以這種格式儲存年份。
04 解法

原因 A 和 D 成立,選組合包含且僅包含 A、D 的選項

小凱確認了:

原因 A:NaN 導致 upcast → 成立
原因 B:字串轉錯 → 不成立(pandas 不會這樣)
原因 C:全預設 float64 → 不成立(pandas 不會這樣)
原因 D:CSV 本身有 2006.0 → 成立

正確答案要包含 A 和 D,而且不包含 B 和 C。四個總選項中,「原因 A、原因 D」對應選項 B。這就是選項 B 講的:原因 A、原因 D

技術版:pandas dtype 類型推斷機制精讀

中級考試大概率會考程式碼跟公式,所以這部分你還是要學。但如果現在學起來很痛苦,可以先跳過,等讀完其他題目回頭再來。

Step 1 純故事版

想像一個倉庫,每個貨架只能放同一種規格的箱子。整數箱子(int64)放不了「沒有貨」的空槽,只有浮點數箱子(float64)才有一個叫做 NaN 的特殊空槽。所以只要有一格是空的,整個貨架就必須換成浮點數箱子。CSV 裡本身就有小數點的數字,一開始就是浮點數箱子。這兩種情況都讓 Year 欄位最後放在浮點數貨架(float64)上。

Step 2 中文 ↔ 程式碼對照
情境pandas 行為
Year 欄全是整數,無缺失值dtype: int64
Year 欄有缺失值(NaN)dtype: float64(int64 無法存 NaN)
CSV 中年份寫成 2006.0dtype: float64(看到小數點就是 float)
解決方案:可空整數型別dtype: Int64(大寫 I,pandas 擴充型別)
強制轉整數(去除 NaN 後)data['Year'].fillna(0).astype(int)
Step 3 符號角色表
int64
numpy 的 64 位元有符號整數,無法存放 NaN,範圍 -2⁶³ 到 2⁶³-1。
float64
numpy 的 64 位元浮點數,可存放 NaN(IEEE 754 標準中的特殊值),因此成為有缺失整數的預設容器。
Int64(大寫 I)
pandas 擴充的可空整數型別(Nullable Integer),可以同時存整數和 NaN,是 pandas 1.0 後的解決方案。
NaN
Not a Number,浮點數標準(IEEE 754)中定義的特殊值,pandas 用它表示缺失值。
dtype inference
pandas 在 read_csv 時自動推斷每欄資料型別的機制,依據欄位中的值決定最合適的 numpy dtype。
Step 4 完整公式對應

本題沒有數學公式,核心是 pandas 的型別推斷規則:

  • 欄位全為整數且無 NaN → int64
  • 欄位有整數且有 NaN → float64(因 int64 無法存 NaN)
  • 欄位有帶小數點的值 → float64
  • 欄位有文字和數字混合 → object
Step 5 自我複述
  1. 為什麼 numpy 的 int64 無法存 NaN?NaN 是什麼型別的值?
  2. pandas 的 Int64(大寫 I)和 numpy 的 int64(小寫 i)差別在哪?
  3. 讀完 CSV 後發現 Year 是 float64,如何判斷是「因為有 NaN」還是「因為 CSV 本身有小數點」?
  4. 如果想把 float64 的 Year 欄轉成整數且保留 NaN,應該用哪個方法?
  5. pandas 的 dtype inference 對效能有什麼影響?大型 CSV 該怎麼指定 dtype?
05 陷阱

為什麼其他總選項是錯的

選項 A 原因 B、原因 C

字面在說什麼:字串轉換出錯和「pandas 全部讀成 float64」這兩個原因導致了 float64。

為什麼不對:原因 B 不成立:pandas 讀到純數字字串時不會「出錯變成浮點數」,它有自動型別推斷機制,會嘗試轉成整數或浮點數,但不是「出錯」。原因 C 不成立:pandas 不會把所有數值都讀成 float64,整數欄無缺失時會讀成 int64。

誰會選錯:對 pandas 的自動型別推斷機制不熟悉、誤以為「字串一定會造成問題」的人,或者誤記了「pandas 預設 float」這個說法的人。

選項 C 原因 A、原因 B、原因 D

字面在說什麼:NaN、字串轉換出錯、CSV 有小數點這三個原因都導致了 float64。

為什麼不對:原因 A 和 D 確實成立,但原因 B 不成立。pandas 讀純數字字串(如 "2006")時,是正常的型別轉換,不是「出錯」。如果 CSV 中 Year 欄有 "2006" 這樣的字串,pd.read_csv 會嘗試把它轉為整數 2006,不會無緣無故變成 float64。

誰會選錯:認為「字串也可能導致浮點數問題」的人,選了多一個不必要的原因。

選項 D 原因 C、原因 D

字面在說什麼:pandas 全部讀成 float64 和 CSV 本身有小數點,這兩個原因造成 float64。

為什麼不對:原因 D 成立,但原因 C 不成立。「pandas 預設將所有數值讀成 float64」是錯誤的說法,整數欄(無缺失值)會被讀成 int64,而且選項 D 包含 C 卻漏掉了 A(NaN 導致 upcast),答案不完整。

誰會選錯:只記得「看到 2006.0 就是 float」,但沒想到 NaN 也是重要原因的人。

06 變形

同個考點下次怎麼變形

變形 1 邊界

直覺:如果 Year 欄全部都是整數、無缺失值,pandas 會讀成什麼型別?

答案:int64。pandas 讀到一欄全部都是不帶小數點的整數且沒有缺失值,類型推斷結果是 int64(64 位元整數)。這是最「乾淨」的情況,不需要升類型。用 data.dtypes 可以確認。

變形 2 反例

直覺:如果一欄同時有數字字串("2006")和真正的 NaN,pandas 會讀成什麼型別?

答案:object(字串)。如果一欄混合了數字字串和真正的 NaN,pandas 讀到後整欄型別是 object,因為 NaN 在 object 欄中以 Python None 或 numpy nan 儲存。這時需要先用 pd.to_numeric(col, errors='coerce') 轉換,把字串數字轉成浮點數、無法轉的值設為 NaN,再視需要處理缺失值。

變形 3 升級版

直覺:如何在 read_csv 時就指定 Year 欄為整數型別,避免被讀成 float?

答案:用 dtype 參數:pd.read_csv('vgsales.csv', dtype={'Year': 'Int64'})。注意要用大寫 'Int64'(pandas 的可空整數型別),而不是小寫 'int64'(numpy 的 int64),因為 numpy int64 無法處理 NaN,如果 CSV 有缺失值會直接報錯。Int64 允許 NaN 存在,是更安全的選擇。

變形 4 跨領域

直覺:除了 Year 欄,哪些欄位的型別問題最常在實際資料中遇到?

答案:ID 欄(身分證號、訂單號):原始是整數,但如果含有前導零(如 "00123")或字串格式,應該存成 object 而非 int。日期欄:pd.read_csv 預設把日期讀成 object(字串),需要用 parse_dates 參數或 pd.to_datetime() 轉成 datetime64。布林欄:True/False 可能被讀成 bool 或 object,取決於 CSV 的實際內容(True vs "True")。

變形 5 評估指標

直覺:載入資料後如何快速確認哪些欄位有缺失值、哪些型別不對?

答案:兩行程式碼搞定:data.dtypes 列出所有欄位的型別、data.isnull().sum() 列出每欄缺失值個數。看完這兩個輸出,就能確定哪些欄位需要補缺失值、哪些型別需要轉換。這是探索性資料分析(EDA)的標準開局步驟。

07 延伸

想再往下看,這 5 個

出處

iPAS 經濟部產業人才能力鑑定 ・ 114 年第二梯次 iPAS AI 應用規劃師 中級 科目二 大數據處理分析與應用 第 43 題

查看官方原文 PDF