Pandas 索引
索引(Index)是 Pandas 中用來標識和存取資料列的標籤。理解索引的運作對於有效操作 DataFrame 非常重要。
什麼是索引
每個 DataFrame 都有一個索引,預設是從 0 開始的整數:
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35]
})
print(df)
name age
0 Alice 25
1 Bob 30
2 Charlie 35
左邊的 0、1、2 就是索引。
查看索引
print(df.index)
# RangeIndex(start=0, stop=3, step=1)
設定索引
建立時指定索引
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35]
}, index=['a', 'b', 'c'])
將欄位設為索引
df = pd.DataFrame({
'id': [101, 102, 103],
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35]
})
# 將 id 欄設為索引
df = df.set_index('id')
print(df)
name age
id
101 Alice 25
102 Bob 30
103 Charlie 35
直接指定索引
df.index = ['x', 'y', 'z']
重設索引
將索引還原成預設的整數索引:
# 原本的索引會變成一個欄位
df = df.reset_index()
# 如果不需要保留原本的索引
df = df.reset_index(drop=True)
使用索引選取資料
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35]
}, index=['a', 'b', 'c'])
# 用 loc 以索引標籤選取
print(df.loc['a'])
print(df.loc['a':'b'])
檢查索引中是否存在值
print('a' in df.index) # True
print('x' in df.index) # False
索引排序
# 按索引排序
df = df.sort_index()
# 降冪排序
df = df.sort_index(ascending=False)
索引運算
重新命名索引
# 使用 rename()
df = df.rename(index={'a': 'A', 'b': 'B'})
# 直接修改索引名稱屬性
df.index.name = 'user_id'
索引唯一性
# 檢查索引是否唯一
print(df.index.is_unique) # True 或 False
# 找出重複的索引
print(df.index.duplicated())
多層索引(MultiIndex)
Pandas 支援多層索引,適合處理階層式資料:
df = pd.DataFrame({
'year': [2023, 2023, 2024, 2024],
'quarter': ['Q1', 'Q2', 'Q1', 'Q2'],
'sales': [100, 150, 120, 180]
})
# 設定多層索引
df = df.set_index(['year', 'quarter'])
print(df)
sales
year quarter
2023 Q1 100
Q2 150
2024 Q1 120
Q2 180
選取多層索引的資料:
# 選取 2023 年的資料
df.loc[2023]
# 選取 2023 年 Q1 的資料
df.loc[(2023, 'Q1')]
索引的常用屬性
df.index.name # 索引名稱
df.index.dtype # 索引資料型別
df.index.values # 索引值的 NumPy 陣列
df.index.tolist() # 轉成 list
len(df.index) # 索引長度
索引的實用技巧
用欄位值快速查詢
當某欄位經常用來查詢時,可以設為索引以提升效能:
# 設定 user_id 為索引
df = df.set_index('user_id')
# 快速查詢特定 user
user_data = df.loc[12345]
保留原索引的操作
有些操作會改變索引,如果要保留原本的對應關係,可以先 reset:
# 排序後重設索引
df_sorted = df.sort_values('age').reset_index(drop=True)