? 今日目標
- 掌握 Pandas 的索引體系(Index / MultiIndex)
- 使用
set_index()
和reset_index()
管理數據索引 - 理解
pivot_table
與melt
、stack/unstack
重塑數據形態 - 初步理解“寬表”與“長表”在數據分析與可視化中的應用場景
📚 一、深入理解 Pandas 的索引系統
1. 默認索引 vs 自定義索引
df = pd.read_csv("./data/students_cleaned.csv")# 自定義“姓名”為索引列
df_indexed = df.set_index("姓名")
print(df_indexed.head())# 還原索引為普通列
df_reset = df_indexed.reset_index()
2. 多級索引(MultiIndex)
df_multi = df.set_index(["性別", "是否及格"])
print(df_multi.head())# 多級索引選擇
print(df_multi.loc[("男", True)])
📊 二、數據透視表(pivot_table)
類似 Excel 的數據透視功能,可做匯總/分組/聚合操作
# 性別 + 及格情況的平均成績
pivot = pd.pivot_table(df, values="成績", index="性別", columns="是否及格", aggfunc="mean")
print(pivot)
🔁 三、數據重塑:長表 ? 寬表
1. melt(寬表 → 長表)
df_melted = pd.melt(df, id_vars=["姓名", "性別"], value_vars=["成績", "是否及格"])
print(df_melted.head())
2. pivot(長表 → 寬表)
# 從 melt 回 pivot
df_pivot = df_melted.pivot(index=["姓名", "性別"], columns="variable", values="value")
print(df_pivot.head())
3. stack & unstack
stacked = df.set_index(["姓名", "性別"]).stack()
print(stacked.head())unstacked = stacked.unstack()
print(unstacked.head())
🧪 今日練習任務建議
-
使用
set_index
和reset_index
操作學生數據 -
創建一個以“性別 + 是否及格”為索引的多級索引表
-
統計不同性別在及格與否下的平均成績(pivot_table)
-
使用
melt
將成績 & 是否及格轉換為“指標名 + 值”形式 -
使用
stack/unstack
查看層級結構變化data/students_cleaned.csv如數如圖:
代碼示例:
import pandas as pd import os# 數據路徑 input_path = "data/students_cleaned.csv" if not os.path.exists(input_path):raise FileNotFoundError("? 缺少 students_cleaned.csv,請先運行 clean_data.py")# 加載數據 df = pd.read_csv(input_path) print("? 已加載數據:") print(df.head())# ========== 一、索引操作 ==========print("\n👉 使用 set_index() 將姓名設為索引:") df_indexed = df.set_index("姓名") print(df_indexed.head())print("\n🔁 使用 reset_index() 還原索引:") df_reset = df_indexed.reset_index() print(df_reset.head())# ========== 二、多級索引 ==========print("\n📦 設置多級索引(性別 + 是否及格):") df_multi = df.set_index(["性別", "是否及格"]) print(df_multi.head())print("\n🔍 查詢:性別為 '女' 且 及格 的學生:") print(df_multi.loc[("女", True)])# ========== 三、pivot_table 操作 ==========print("\n📊 pivot_table 統計性別 + 是否及格下的平均成績:") pivot = pd.pivot_table(df, values="成績", index="性別", columns="是否及格", aggfunc="mean") print(pivot)# ========== 四、melt 數據重塑 ==========print("\n🔄 使用 melt 變長表結構(指標列合并):") df_melted = pd.melt(df, id_vars=["姓名", "性別"], value_vars=["成績", "是否及格"]) print(df_melted.head())# ========== 五、pivot 還原寬表結構 ==========print("\n🔁 使用 pivot 將 melt 數據還原回寬表:") df_pivot = df_melted.pivot(index=["姓名", "性別"], columns="variable", values="value") print(df_pivot.head())# ========== 六、stack 和 unstack ==========print("\n📚 使用 stack 增加層級結構(列 → 行):") df_stacked = df.set_index(["姓名", "性別"]).stack() print(df_stacked.head())print("\n📂 使用 unstack 還原結構(行 → 列):") df_unstacked = df_stacked.unstack() print(df_unstacked.head())
運行結果:
? 已加載數據:姓名 性別 成績 是否及格 0 張三 男 88.00 True 1 李四 女 81.75 True 2 王五 男 59.00 False 3 田七 女 81.75 True 4 趙六 女 92.00 True👉 使用 set_index() 將姓名設為索引:性別 成績 是否及格 姓名 張三 男 88.00 True 李四 女 81.75 True 王五 男 59.00 False 田七 女 81.75 True 趙六 女 92.00 True🔁 使用 reset_index() 還原索引:姓名 性別 成績 是否及格 0 張三 男 88.00 True 1 李四 女 81.75 True 2 王五 男 59.00 False 3 田七 女 81.75 True 4 趙六 女 92.00 True📦 設置多級索引(性別 + 是否及格):姓名 成績 性別 是否及格 男 True 張三 88.00 女 True 李四 81.75 男 False 王五 59.00 女 True 田七 81.75True 趙六 92.00🔍 查詢:性別為 '女' 且 及格 的學生:姓名 成績 性別 是否及格 女 True 李四 81.75True 田七 81.75True 趙六 92.00📊 pivot_table 統計性別 + 是否及格下的平均成績: 是否及格 False True 性別 女 NaN 85.166667 男 59.0 88.000000🔄 使用 melt 變長表結構(指標列合并):姓名 性別 variable value 0 張三 男 成績 88.0 1 李四 女 成績 81.75 2 王五 男 成績 59.0 3 田七 女 成績 81.75 4 趙六 女 成績 92.0🔁 使用 pivot 將 melt 數據還原回寬表: variable 成績 是否及格 姓名 性別 張三 男 88.0 1.0 李四 女 81.75 1.0 王五 男 59.0 0.0 田七 女 81.75 1.0 趙六 女 92.0 1.0📚 使用 stack 增加層級結構(列 → 行): 姓名 性別 張三 男 成績 88.0是否及格 True 李四 女 成績 81.75是否及格 True 王五 男 成績 59.0 dtype: object📂 使用 unstack 還原結構(行 → 列):成績 是否及格 姓名 性別 張三 男 88.0 True 李四 女 81.75 True 王五 男 59.0 False 田七 女 81.75 True 趙六 女 92.0 True
🧾 今日總結
- 索引是 Pandas 操作效率與表達力的核心
- 多級索引可構建靈活的數據結構,適合多維度聚合分析
pivot_table
是強大而高效的“表格重建”工具melt
/pivot
/stack
/unstack
是數據“變形”關鍵方法