大家好,歡迎來到數據新手村的第二十天!昨天我們學會了如何處理數據中的「缺失值」,讓我們的資料集不再有空洞。
但資料清洗的挑戰還沒結束。想像一下,如果一個紀錄價格的欄位,被當成了「文字」;或者一個訂單日期,被當成了「純文字」,會發生什麼事?
這就是「資料類型 (Data Type)」不正確所導致的問題。今天,我們就要來學習如何幫 DataFrame 中的每一欄,找到它們正確的「身份」,這就是資料類型轉換。
.info()
神器在動手修正之前,我們得先找出哪些欄位的類型是錯誤的。在 Day 17,我們學過的 df.info()
正是執行這項任務的最佳工具。
讓我們再次讀取 Olist 的訂單資料表,並檢視它的「身分證」。
import pandas as pd
# 讀取訂單主表
orders_df = pd.read_csv('../../data/olist_datasets/olist_orders_dataset.csv')
# 呼叫 .info() 來檢視所有欄位的資訊
orders_df.info()
輸出結果:
1 customer_id 99441 non-null object
2 order_status 99441 non-null object
3 order_purchase_timestamp 99441 non-null object
4 order_approved_at 99281 non-null object
5 order_delivered_carrier_date 97658 non-null object
6 order_delivered_customer_date 96476 non-null object
7 order_estimated_delivery_date 99441 non-null object
dtypes: object(8)
memory usage: 6.1+ MB
觀察重點:
從輸出的結果中,您會發現所有跟「時間」相關的欄位,例如 order_purchase_timestamp, order_approved_at 等,它們的 Dtype (資料類型) 都是 object。
在 Pandas 中,object 通常就代表「文字 (string)」。這證實了我們的猜想:Pandas 並沒有自動將這些日期文字辨識為「時間」,我們必須手動轉換它們。
.astype() 是 Pandas 中最通用的類型轉換方法,可以用來在各種基礎類型之間轉換(例如:int, float, str)。
舉個例子,如果我們有一個浮點數的欄位,想把它轉成整數:
# 建立一個範例 DataFrame
df_sample = pd.DataFrame({'price': [99.0, 150.0, 200.0]})
print(f"原始 dtype: {df_sample['price'].dtype}")
# 使用 .astype() 將 float64 轉為 int64
df_sample['price'] = df_sample['price'].astype(int)
print(f"轉換後 dtype: {df_sample['price'].dtype}")
print(df_sample)
輸出結果:
原始 dtype: float64
轉換後 dtype: int64
price
0 99
1 150
2 200
雖然 .astype() 很方便,但對於「日期時間」這種複雜的類型,Pandas 提供了一個更強大的專用魔法棒。
pd.to_datetime() 是專門用來將各種格式的文字,解析並轉換成 Pandas 標準的 datetime 物件的函式。
實戰:轉換 Olist 訂單時間
讓我們來修正 order_purchase_timestamp 這個欄位。
# 檢視轉換前的類型
print(f"轉換前 order_purchase_timestamp 的 dtype: {orders_df['order_purchase_timestamp'].dtype}")
print(f"轉換前第一筆資料的類型: {type(orders_df['order_purchase_timestamp'][0])}")
print("\n" + "="*30 + "\n")
# 進行轉換
orders_df['order_purchase_timestamp'] = pd.to_datetime(orders_df['order_purchase_timestamp'])
# 檢視轉換後的類型
print(f"轉換後 order_purchase_timestamp 的 dtype: {orders_df['order_purchase_timestamp'].dtype}")
print(f"轉換後第一筆資料的類型: {type(orders_df['order_purchase_timestamp'][0])}")
輸出結果:
轉換前 order_purchase_timestamp 的 dtype: object
轉換前第一筆資料的類型: <class 'str'>
==============================
轉換後 order_purchase_timestamp 的 dtype: datetime64[ns]
轉換後第一筆資料的類型: <class 'pandas._libs.tslibs.timestamps.Timestamp'>
您會發現,欄位的 dtype 變成了 datetime64[ns],這就是 Pandas 中標準的時間類型。
datetime 型態的超能力
一旦轉換為 datetime 型態,您的欄位就解鎖了超能力!我們可以透過 .dt accessor,輕易地提取出時間的各個組成部分。
# 讓我們看看轉換後的第一筆訂單時間
first_order_time = orders_df['order_purchase_timestamp'][0]
print(f"第一筆訂單的時間是: {first_order_time}\n")
# 使用 .dt 提取各種時間資訊
print(f"年份: {first_order_time.year}")
print(f"月份: {first_order_time.month}")
print(f"日期: {first_order_time.day}")
print(f"星期幾 (0=週一, 6=週日): {first_order_time.dayofweek}")
print(f"當天的第幾小時: {first_order_time.hour}")
輸出結果:
第一筆訂單的時間是: 2017-10-02 10:56:33
年份: 2017
月份: 10
日期: 2
星期幾 (0=週一, 6=週日): 0
當天的第幾小時: 10
是不是非常方便!這些操作對於文字類型來說是完全不可能的。這就是資料類型轉換的威力。
今天我們學會了如何診斷並修正 DataFrame 中的資料類型。請記住這兩個重點:
用 .info() 做健康檢查。
用 .astype() 處理一般類型,用 pd.to_datetime() 處理時間文字。
正確的資料類型不僅是為了讓表格看起來整潔,更是為了解鎖後續分析的強大能力。
我們已經處理了「空格子」和「填錯內容的格子」。明天,Day 21,我們將學習如何從現有的資料中,創造出全新的洞見——這就是特徵工程的起點:在 Pandas 中新增與刪除欄位。