本文 AI 產出,尚未審核

Python 資料清理與轉換

簡介

在資料科學與機器學習的工作流程中,資料清理與轉換(Data Cleaning & Transformation)是不可或缺的基礎步驟。即使模型再先進,若輸入的資料品質不佳,最終的預測結果也會受到嚴重影響。
本單元旨在說明如何使用 Python 內建與常見的第三方套件(如 pandasnumpyre)快速、可靠地完成資料清理與格式轉換,幫助讀者在實務專案中建立乾淨、結構化的資料集。


核心概念

1. 為什麼需要資料清理?

  • 缺失值(NaN、空字串)會導致計算錯誤或模型無法收斂。
  • 重複資料 會讓統計結果偏斜。
  • 不一致的格式(日期、金額、編碼)會讓後續的合併或分組操作變得困難。

2. 常用套件與資料結構

套件 主要功能 常見資料結構
pandas 高效能資料框(DataFrame)操作 DataFrameSeries
numpy 向量化運算、缺失值處理 ndarray
re 正規表達式文字處理 文字字串

小技巧:在 Jupyter Notebook 中,使用 %matplotlib inline 可以即時檢視清理前後的分布圖,幫助判斷是否已成功處理異常值。

3. 缺失值處理

import pandas as pd
import numpy as np

# 建立示範 DataFrame
df = pd.DataFrame({
    "姓名": ["Alice", "Bob", np.nan, "David", "Eve"],
    "年齡": [25, np.nan, 30, 22, None],
    "收入": ["$3,200", "$4,500", "$5,000", None, "$2,800"]
})

# 1. 檢視缺失值概況
print(df.isna().sum())
# 2. 用特定值填補(例如年齡以平均值填補)
df["年齡"] = df["年齡"].fillna(df["年齡"].mean())
# 3. 刪除全為缺失的列
df = df.dropna(subset=["姓名"])
print(df)

以上範例展示了 檢視、填補與刪除 三種常見缺失值處理方式。對於數值欄位,使用平均值或中位數填補是最簡單的做法;對於文字欄位,則可考慮填入 "未知" 或直接刪除該列。

4. 重複資料與不一致格式

# 假設有重複的交易紀錄
transactions = pd.DataFrame({
    "交易編號": [101, 102, 101, 103, 104, 102],
    "金額": [1000, 1500, 1000, 2000, 2500, 1500]
})

# 1. 找出重複列
dup = transactions.duplicated(subset=["交易編號"], keep=False)
print("重複列:\n", transactions[dup])

# 2. 移除重複(保留第一筆)
transactions_clean = transactions.drop_duplicates(subset=["交易編號"], keep="first")
print("移除重複後:\n", transactions_clean)

注意duplicated() 預設只檢查全列相同,若只想比較特定欄位,請使用 subset 參數。

5. 日期與時間的標準化

# 原始資料中日期格式混雜
raw_dates = pd.Series(["2023/01/15", "15-02-2023", "2023.03.20", "April 5, 2023"])

# 使用 pandas.to_datetime 進行彈性解析
clean_dates = pd.to_datetime(raw_dates, errors="coerce", infer_datetime_format=True)
print(clean_dates)

errors="coerce" 會把無法解析的值轉成 NaT(類似 NaN),方便後續的缺失值處理。

6. 文字資料的清理(正規表達式)

import re

# 假設有一欄金額資料,包含美元符號、逗號與空白
money_series = pd.Series([" $3,200 ", "$4,500", "5000", "USD 2,800"])

def clean_money(val):
    # 移除非數字與小數點的字元
    num = re.sub(r"[^\d.]", "", str(val))
    return float(num) if num else np.nan

cleaned_money = money_series.apply(clean_money)
print(cleaned_money)

透過 re.sub() 可以快速去除不需要的符號,將文字型別的金額轉成 浮點數,為後續的數值分析做好準備。

7. 資料類型轉換(Casting)

# 先前的 DataFrame
df["收入"] = cleaned_money   # 直接指派轉換後的 Series

# 確認欄位類型
print(df.dtypes)

# 如需將類別變數轉成 one‑hot 編碼
df_onehot = pd.get_dummies(df["姓名"], prefix="姓名")
print(df_onehot.head())

為了避免 類型不匹配 的錯誤,建議在完成清理後,使用 astype() 明確指定欄位的資料型別。


常見陷阱與最佳實踐

陷阱 說明 最佳實踐
直接修改原始 DataFrame 會導致難以追蹤的副作用 使用 df.copy() 產生副本,或在 Notebook 中保留原始變數
忽略時間區間 日期時間若未統一時區,會在合併或計算差異時出錯 轉換為 UTC 或同一時區 (tz_convert)
過度填補缺失值 用平均值填補過多會降低資料變異性 先分析缺失機制(MCAR、MAR、MNAR),必要時考慮刪除或使用模型預測填補
正規表達式寫得太寬鬆 可能把不相關的字元也去除 測試正則表達式於樣本資料,必要時加上斷言或限定字元範圍
忘記重新設定索引 刪除列或合併後索引可能不連續,導致後續迭代錯誤 使用 reset_index(drop=True) 重新整理索引

小提醒:在大型資料集上執行 apply() 會較慢,盡量改用向量化的 pandasnumpy 方法(如 str.replaceastype)。


實際應用場景

  1. 金融交易資料

    • 需要先將交易時間標準化、去除重複交易、將金額文字轉為數值,再計算每日、每月的交易量與風險指標。
  2. 電商產品評論

    • 清理評論文字中的 HTML 標籤、表情符號,並將評分欄位轉為整數,以便進行情感分析或建立推薦系統。
  3. 醫療病歷資料

    • 針對缺失的血壓、血糖值使用插值或模型預測填補,統一日期格式(出生日期、檢驗日期),確保個資去識別化後再進行統計分析。
  4. 社群媒體抓取

    • 從 API 抓取的 JSON 常包含巢狀結構,需使用 json_normalize 展平,並將時間戳記轉成可讀的 datetime,最後去除重複貼文或廣告。

總結

資料清理與轉換是 資料科學流程的第一道關卡,好與壞直接決定後續分析與模型的可靠性。本文重點回顧如下:

  • 缺失值、重複值與不一致格式 是最常見的問題,使用 pandasisnafillnadrop_duplicates 等函式即可快速處理。
  • 日期、時間與文字 需要透過 to_datetime、正規表達式等方式統一格式,避免在合併或計算時產生錯誤。
  • 資料類型的明確轉換(Casting)與 one‑hot 編碼 能讓模型直接接受乾淨的特徵。
  • 避免常見陷阱,如直接修改原始資料、過度填補或忽略時區,並遵循最佳實踐(使用副本、向量化運算)。

掌握上述技巧後,你就能在 金融、電商、醫療、社群等多種領域,快速把雜亂的原始資料轉化為可供分析與建模的高品質資料集。祝你在 Python 資料處理的旅程中,越走越順!