iT邦幫忙

2025 iThome 鐵人賽

DAY 20
0
自我挑戰組

數據新手村:統計系畢業生 30 天打怪升級之旅系列 第 20

Day 20 - 資料清洗(二):型態決定一切,Pandas 資料類型轉換大法

  • 分享至 

  • xImage
  •  

大家好,歡迎來到數據新手村的第二十天!昨天我們學會了如何處理數據中的「缺失值」,讓我們的資料集不再有空洞。

但資料清洗的挑戰還沒結束。想像一下,如果一個紀錄價格的欄位,被當成了「文字」;或者一個訂單日期,被當成了「純文字」,會發生什麼事?

  • 我們無法計算「文字」的平均價格。
  • 我們也無法計算兩個「文字」之間相差了幾天。

這就是「資料類型 (Data Type)」不正確所導致的問題。今天,我們就要來學習如何幫 DataFrame 中的每一欄,找到它們正確的「身份」,這就是資料類型轉換


1. 診斷問題:再次請出 .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 並沒有自動將這些日期文字辨識為「時間」,我們必須手動轉換它們。

2. 通用轉換工具:.astype()

.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 提供了一個更強大的專用魔法棒。

3. 時間序列的魔法棒:pd.to_datetime() (本篇核心)

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 中新增與刪除欄位。


上一篇
Day 19 - 資料清洗(一):如何優雅地處理缺失值 (Missing Values)
下一篇
Day 21 - 在 Pandas 中新增與刪除欄位
系列文
數據新手村:統計系畢業生 30 天打怪升級之旅21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言