iT邦幫忙

2025 iThome 鐵人賽

DAY 9
0

在資料清理過程中,缺失值 (NaN) 幾乎是必定會遇到的狀況。舉例來說,可能是某一天沒有交易數據、某些欄位沒有填寫完整,又或者資料在蒐集過程中有遺漏。這些 NaN 如果不處理,往往會讓後續的分析或模型訓練出現錯誤,因此今天我們就來示範 Pandas 常見的 NaN 處理方法。

建立範例 DataFrame

我們先用 numpy 的 np.nan 建立一個包含缺失值的小型 DataFrame:

import pandas as pd
import numpy as np

nan_df = pd.DataFrame({
    'A': [1, 2, np.nan, 4, np.nan],
    'B': [5, np.nan, 7, 8, 9],
    'C': [10, 11, 12, np.nan, 14]
})

print("原始 DataFrame (含缺失值):")
print(nan_df)

輸出結果:

     A    B     C
0  1.0  5.0  10.0
1  2.0  NaN  11.0
2  NaN  7.0  12.0
3  4.0  8.0   NaN
4  NaN  9.0  14.0

可以看到 A、B、C 欄都有 NaN。

將 NaN 填補為指定數值

最簡單的方式是用 fillna() 把缺失值補上特定數字。例如補 0:

filled_df_zero = nan_df.fillna(0)
print("\n1. 將所有 NaN 填補為 0:")
print(filled_df_zero)

輸出:

     A    B     C
0  1.0  5.0  10.0
1  2.0  0.0  11.0
2  0.0  7.0  12.0
3  4.0  8.0   0.0
4  0.0  9.0  14.0

這種方式適合數值欄位,但要小心:補 0 可能會影響平均數與統計結果,所以實際情況中要斟酌使用。

使用前一筆資料填補 (forward-fill)

另一種常見策略是用前一筆資料補上缺失,這在時間序列(如股價、氣象數據)中特別常用:

filled_df_ffill = nan_df.ffill()
print("\n2. 使用前一筆資料向下填補 (forward-fill):")
print(filled_df_ffill)

輸出:

     A    B     C
0  1.0  5.0  10.0
1  2.0  5.0  11.0
2  2.0  7.0  12.0
3  4.0  8.0  12.0
4  4.0  9.0  14.0

這裡每個 NaN 都被「上方最近的數值」取代了。

刪除缺失值

有些情況下,缺失值太多或無法合理補值,我們會直接刪除。
刪除列 (row)

dropped_rows_df = nan_df.dropna()
print("\n3. 刪除任何包含 NaN 的資料列:")
print(dropped_rows_df)

輸出:

     A    B     C
0  1.0  5.0  10.0

因為只有第 0 列完全沒有 NaN,所以剩下一筆。
刪除欄 (column)

dropped_cols_df = nan_df.dropna(axis=1)
print("\n4. 刪除任何包含 NaN 的資料行:")
print(dropped_cols_df)

輸出:

Empty DataFrame
Columns: []
Index: [0, 1, 2, 3, 4]

因為每一欄至少都有 NaN,所以最後整個 DataFrame 變成空的。這種情況提醒我們:直接刪除整欄通常只適用於「缺失比例過高且該欄不重要」的情境。

總結

今天示範了幾種 Pandas 處理缺失值的方法:

  • fillna(0) → 補上固定值
  • ffill() → 用前一筆資料補值(適合時間序列)
  • dropna() → 刪除含 NaN 的列或欄

在實務中,該用哪種方式取決於資料型態與分析目的。舉例來說,股價的缺失值比較適合用 前後值補齊,問卷調查的缺失可能需要補上 眾數或平均數,而缺失過多的欄位就要考慮刪除。處理缺失值就像整理資料的一道清潔程序,做得好可以避免後續分析出現錯誤,也能讓模型訓練更穩定。
那今天就先這樣。
/images/emoticon/emoticon29.gif


上一篇
處理數字欄位
系列文
從網路爬蟲到資料洞察的應用9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言