Pandas 過濾資料
過濾(filter)是指根據條件篩選出符合的資料列。這是資料分析中最常用的操作之一。
範例資料
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eva'],
'age': [25, 30, 35, 28, 32],
'city': ['Taipei', 'Tokyo', 'Seoul', 'Taipei', 'Tokyo'],
'salary': [50000, 60000, 70000, 55000, 65000]
})
基本條件過濾
比較運算
# 選取 age > 30 的資料
result = df[df['age'] > 30]
print(result)
輸出:
name age city salary
2 Charlie 35 Seoul 70000
4 Eva 32 Tokyo 65000
背後的原理是布林索引(Boolean indexing):
# 條件運算會產生布林 Series
print(df['age'] > 30)
0 False
1 False
2 True
3 False
4 True
Name: age, dtype: bool
常見比較運算子
df[df['age'] > 30] # 大於
df[df['age'] >= 30] # 大於等於
df[df['age'] < 30] # 小於
df[df['age'] <= 30] # 小於等於
df[df['age'] == 30] # 等於
df[df['age'] != 30] # 不等於
多條件過濾
使用 &(AND)、|(OR)、~(NOT)組合多個條件。
注意:每個條件必須用括號包起來。
AND 條件
# age > 25 且 salary > 55000
result = df[(df['age'] > 25) & (df['salary'] > 55000)]
OR 條件
# age < 26 或 age > 33
result = df[(df['age'] < 26) | (df['age'] > 33)]
NOT 條件
# age 不大於 30
result = df[~(df['age'] > 30)]
複雜條件組合
# (age > 25 且 city == 'Taipei') 或 salary > 65000
result = df[((df['age'] > 25) & (df['city'] == 'Taipei')) | (df['salary'] > 65000)]
字串條件過濾
等於特定值
result = df[df['city'] == 'Taipei']
包含特定文字
result = df[df['name'].str.contains('a')] # 名字包含 'a'
開頭或結尾
result = df[df['name'].str.startswith('A')]
result = df[df['name'].str.endswith('e')]
不區分大小寫
result = df[df['name'].str.lower() == 'alice']
# 或
result = df[df['name'].str.contains('alice', case=False)]
isin() 過濾
檢查值是否在給定的列表中:
# city 在 ['Taipei', 'Tokyo'] 中
result = df[df['city'].isin(['Taipei', 'Tokyo'])]
排除特定值:
# city 不在 ['Seoul'] 中
result = df[~df['city'].isin(['Seoul'])]
between() 過濾
選取範圍內的值:
# age 在 25 到 32 之間(包含邊界)
result = df[df['age'].between(25, 32)]
query() 方法
使用類似 SQL 的語法過濾:
# 基本用法
result = df.query('age > 30')
# 多條件
result = df.query('age > 25 and salary > 55000')
result = df.query('age < 26 or age > 33')
# 字串比較
result = df.query('city == "Taipei"')
# 使用變數(加 @)
min_age = 30
result = df.query('age > @min_age')
query() 的好處是語法更直覺,不需要重複寫 df['欄位']。
過濾空值
# 選取 age 不是空值的列
result = df[df['age'].notna()]
# 選取 age 是空值的列
result = df[df['age'].isna()]
使用 loc 過濾
loc 可以同時過濾列和選取欄位:
# 過濾 age > 30,只選取 name 和 salary 欄位
result = df.loc[df['age'] > 30, ['name', 'salary']]
取得過濾後的索引
# 取得符合條件的索引
indices = df[df['age'] > 30].index
print(indices) # Index([2, 4], dtype='int64')
過濾後重設索引
過濾後索引可能不連續,可以重設:
result = df[df['age'] > 30].reset_index(drop=True)