本文 AI 產出,尚未審核

pandas DataFrame 操作實務指南

簡介

在 Python 的資料科學生態系中,pandas 是最常被使用的資料處理套件。它提供了功能強大的 DataFrame 結構,讓我們能以類似資料庫表格的方式,彈性且高效地進行清理、轉換與分析。無論是日常的 CSV 匯入、金融時間序列的切割,或是機器學習前的特徵工程,DataFrame 都是不可或缺的基礎工具。

本篇文章針對 初學者到中級開發者,從核心概念到實務技巧,系統性說明如何操作 pandas DataFrame,並提供多個可直接套用的程式碼範例,協助你在真實專案中快速上手、避免常見陷阱。


核心概念

1️⃣ 建立與檢視 DataFrame

方法 說明
pd.DataFrame(data) 由字典、list、NumPy 陣列等建立
df.head() / df.tail() 觀察前/後幾筆資料
df.info() 顯示欄位型別與缺失值概況
df.describe() 數值欄位的統計摘要
import pandas as pd
import numpy as np

# 由字典建立 DataFrame
data = {
    "日期": pd.date_range("2023-01-01", periods=5, freq="D"),
    "商品": ["A", "B", "A", "C", "B"],
    "銷售額": [1200, 850, 950, 430, 770],
    "庫存": [30, 45, 28, 50, 40]
}
df = pd.DataFrame(data)

print(df.head())
print("\n欄位資訊:")
df.info()

重點pd.date_range 可直接產生時間序列,對於時間序列分析非常實用。


2️⃣ 資料選取(Selection)

2.1 依欄位名稱選取

# 取出單一欄位 → Series
sales = df["銷售額"]

# 同時取出多個欄位 → DataFrame
subset = df[["日期", "銷售額"]]

2.2 依列條件篩選(Boolean Indexing)

# 篩選商品為 "A" 且銷售額 > 900 的資料
filtered = df[(df["商品"] == "A") & (df["銷售額"] > 900)]
print(filtered)

2.3 使用 .loc.iloc

方法 說明
df.loc[row_label, col_label] 標籤(label)選取
df.iloc[row_index, col_index] 位置(integer)選取
# 使用 .loc 依標籤選取第 2~4 列、"商品" 與 "庫存" 欄位
selected = df.loc[1:3, ["商品", "庫存"]]
print(selected)

# 使用 .iloc 依位置選取第 0、2 列與第 1、3 欄位
selected2 = df.iloc[[0, 2], [1, 3]]
print(selected2)

3️⃣ 新增、刪除與變更欄位

# 新增計算欄位:單位售價 = 銷售額 / 庫存
df["單位售價"] = df["銷售額"] / df["庫存"]

# 刪除欄位:使用 drop
df = df.drop(columns=["庫存"])

# 重新命名欄位
df = df.rename(columns={"單位售價": "售價 (元/件)"})
print(df)

小技巧assign() 可在不改變原始 DataFrame 的情況下產生新欄位,適合串接多個操作。

df2 = df.assign(毛利=lambda x: x["銷售額"] * 0.2)
print(df2)

4️⃣ 缺失值處理(Missing Data)

# 假設在 "銷售額" 欄位加入缺失值
df.loc[2, "銷售額"] = np.nan
print(df)

# 方法一:直接刪除含缺失值的列
df_dropna = df.dropna(subset=["銷售額"])

# 方法二:填補缺失值(以平均值填補)
mean_sales = df["銷售額"].mean()
df_fillna = df["銷售額"].fillna(mean_sales)
df["銷售額"] = df_fillna
print(df)

注意dropna 會回傳新的 DataFrame,除非使用 inplace=True,否則原始資料不會被改變。


5️⃣ 資料聚合與分組(GroupBy)

# 以商品分組,計算每組的總銷售額與平均單位售價
grouped = df.groupby("商品").agg({
    "銷售額": "sum",
    "售價 (元/件)": "mean"
}).reset_index()

print(grouped)

5.1 多層次分組

# 加入日期月份作為第二層分組
df["月份"] = df["日期"].dt.month
multi_group = df.groupby(["商品", "月份"]).agg({
    "銷售額": ["sum", "mean"],
    "售價 (元/件)": "max"
})
print(multi_group)

常見陷阱與最佳實踐

陷阱 可能的結果 建議的做法
直接修改原始 DataFrame(忘記 inplace=False 造成不可預期的資料變動 盡量使用方法返回新物件,或明確設定 inplace=True
使用 df.append() 逐筆加入 效能極差(O(n²)) 改用一次性 pd.concat([df, new_rows])
忽略資料型別(例如日期被視為字串) 失去時間序列功能 讀取時使用 parse_dates,或手動 pd.to_datetime()
**布林索引中使用 &、` ` 時忘記加括號** 產生 ValueError: The truth value of a Series is ambiguous
分組聚合後欄位名稱變成多層索引 後續存取不直觀 使用 agg(...).reset_index()rename_axis(None, axis=1) 重新命名

最佳實踐小結

  1. 先檢查資料型別df.dtypes,確保數值、時間、類別欄位正確。
  2. 避免鏈式賦值警告:如 df['col'][mask] = value,改用 df.loc[mask, 'col'] = value
  3. 使用向量化運算:盡量避免 for 迴圈,pandas 內建的運算速度更快。
  4. 記得釋放記憶體:大型資料集完成處理後,可使用 del dfgc.collect()

實際應用場景

場景 典型操作 為何使用 pandas
銷售報表自動化 讀取多個 CSV、合併、彙總、輸出 Excel 支援多種檔案格式、快速分組聚合
金融時間序列分析 下載股票資料、計算移動平均、缺失值補齊 強大的時間索引 (DatetimeIndex) 與重抽樣功能
客戶行為分群 依屬性分組、計算 KPI、標籤化 groupby + apply 可靈活自訂聚合邏輯
機器學習前的特徵工程 缺失值填補、類別編碼、特徵縮放 與 scikit-learn Pipeline 無縫結合
資料庫 ETL 從 MySQL 讀取 → 轉換 → 匯入 PostgreSQL read_sql, to_sql 直接對接 DB,減少中間檔案

範例:將每日銷售資料匯入資料庫,並自動產生每月彙總表

import sqlalchemy

# 建立資料庫連線
engine = sqlalchemy.create_engine("postgresql://user:pwd@localhost:5432/salesdb")

# 讀取 CSV 並寫入資料表
df_monthly = pd.read_csv("sales_2023_Jan.csv")
df_monthly.to_sql("daily_sales", con=engine, if_exists="append", index=False)

# 產生每月彙總
summary = pd.read_sql("""
    SELECT DATE_TRUNC('month', 日期) AS month,
           商品,
           SUM(銷售額) AS total_sales
    FROM daily_sales
    GROUP BY month, 商品
    ORDER BY month
""", con=engine)

print(summary.head())

總結

  • pandas DataFrame 是 Python 資料處理的核心工具,掌握其建立、選取、變更、缺失值處理與分組聚合等操作,能大幅提升日常工作的效率。
  • 在實務開發中,避免常見陷阱(如鏈式賦值、低效的逐筆加入)與 遵循最佳實踐(向量化、明確資料型別)是保證程式穩定與效能的關鍵。
  • 透過本文的範例,你可以快速將 CSV、資料庫或 API 取得的原始資料,轉換成可直接用於報表、分析或機器學習的結構化資料。

希望這篇 pandas DataFrame 操作 的教學能成為你在資料處理路上可靠的參考手冊,祝你寫程式順利、資料分析得心應手!