WeHelp
Pandas 是 Python 用來做資料分析和處理的熱門工具,也是資料分析師的必備技能。
  1. 簡介、安裝、快速開始
  2. Series 單維度資料
  3. Series 實務案例
  4. DataFrame 雙維度資料
  5. DataFrame 實務案例
  6. 過濾資料的範例說明
  7. 缺失填補的範例說明
  8. 排序資料的範例說明
  9. CSV、Excel 檔案存取
  10. JSON 格式檔案存取
過濾資料的範例說明
# Pandas 過濾資料範例與常用技巧 Pandas 中最常見的資料過濾方式,是建立一個由 `True` / `False` 組成的條件,再將條件傳入 `DataFrame`。 以下使用範例資料: ```python import pandas as pd import numpy as np df = pd.DataFrame({ "name": ["Alice", "Bob", "Charlie", "David", "Eva"], "age": [25, 32, 28, 40, 22], "city": ["Taipei", "Taichung", "Taipei", "Kaohsiung", "Taipei"], "score": [88, 75, 92, 60, np.nan], "date": pd.to_datetime([ "2024-01-10", "2024-02-15", "2024-03-20", "2024-04-05", "2024-05-12" ]) }) print(df) ``` 資料如下: ```text name age city score date 0 Alice 25 Taipei 88.0 2024-01-10 1 Bob 32 Taichung 75.0 2024-02-15 2 Charlie 28 Taipei 92.0 2024-03-20 3 David 40 Kaohsiung 60.0 2024-04-05 4 Eva 22 Taipei NaN 2024-05-12 ``` --- ## 1. 根據單一條件過濾 例如,篩選年齡大於 30 歲的資料: ```python result = df[df["age"] > 30] print(result) ``` 結果: ```text name age city score date 1 Bob 32 Taichung 75.0 2024-02-15 3 David 40 Kaohsiung 60.0 2024-04-05 ``` 也可以使用其他比較運算子: ```python df[df["age"] == 25] # 等於 25 df[df["age"] != 25] # 不等於 25 df[df["age"] >= 30] # 大於等於 30 df[df["age"] < 30] # 小於 30 ``` ### 注意 Pandas 中的等於是 `==`,不是單一的 `=`: ```python df[df["age"] == 25] # 正確 ``` --- ## 2. 多個條件:AND、OR、NOT ### AND:同時符合多個條件 篩選年齡大於 25,且分數至少為 80: ```python result = df[(df["age"] > 25) & (df["score"] >= 80)] ``` 結果: ```text name age city score date 2 Charlie 28 Taipei 92.0 2024-03-20 ``` ### OR:符合其中一個條件 篩選城市為 Taipei 或 Taichung: ```python result = df[ (df["city"] == "Taipei") | (df["city"] == "Taichung") ] ``` ### NOT:排除某個條件 排除 Taipei: ```python result = df[df["city"] != "Taipei"] ``` 也可以使用 `~` 反轉條件: ```python result = df[~(df["city"] == "Taipei")] ``` ### 非常重要:條件必須加括號 錯誤寫法: ```python df[df["age"] > 25 & df["score"] >= 80] ``` 正確寫法: ```python df[(df["age"] > 25) & (df["score"] >= 80)] ``` Pandas 使用: - `&` 代表 AND - `|` 代表 OR - `~` 代表 NOT 不要使用 Python 的 `and`、`or`: ```python # 錯誤 df[(df["age"] > 25) and (df["score"] >= 80)] # 正確 df[(df["age"] > 25) & (df["score"] >= 80)] ``` --- ## 3. 使用 `isin()` 篩選多個值 如果要篩選多個城市,可以使用 `isin()`: ```python result = df[df["city"].isin(["Taipei", "Kaohsiung"])] ``` 這相當於: ```python (df["city"] == "Taipei") | (df["city"] == "Kaohsiung") ``` 排除這些城市: ```python result = df[~df["city"].isin(["Taipei", "Kaohsiung"])] ``` 也可以套用在數字欄位: ```python result = df[df["age"].isin([22, 25, 32])] ``` --- ## 4. 使用 `between()` 篩選範圍 例如,篩選年齡介於 25 到 35 歲: ```python result = df[df["age"].between(25, 35)] ``` `between()` 預設包含兩端: ```python df["age"].between(25, 35) ``` 相當於: ```python (df["age"] >= 25) & (df["age"] <= 35) ``` 如果不包含邊界,可以指定: ```python result = df[df["age"].between(25, 35, inclusive="neither")] ``` 其他選項包括: ```python inclusive="both" # 預設,包含上下界 inclusive="left" # 包含左界 inclusive="right" # 包含右界 inclusive="neither" # 都不包含 ``` --- ## 5. 字串過濾:`str.contains()` 篩選城市名稱中包含 `"Tai"` 的資料: ```python result = df[df["city"].str.contains("Tai")] ``` 結果會包含: ```text name age city score date 0 Alice 25 Taipei 88.0 2024-01-10 2 Charlie 28 Taipei 92.0 2024-03-20 4 Eva 22 Taipei NaN 2024-05-12 ``` ### 忽略大小寫 ```python result = df[ df["city"].str.contains("tai", case=False, na=False) ] ``` ### 避免缺失值造成錯誤 如果字串欄位可能含有 `NaN`,建議使用: ```python df["city"].str.contains("Tai", na=False) ``` `na=False` 表示缺失值視為不符合條件。 ### 其他常用字串方法 ```python df[df["name"].str.startswith("A")] # 以 A 開頭 df[df["name"].str.endswith("e")] # 以 e 結尾 df[df["name"].str.len() > 4] # 字串長度大於 4 df[df["name"].str.lower() == "alice"] # 忽略大小寫比較 ``` --- ## 6. 處理缺失值:`isna()` 與 `notna()` 篩選分數缺失的資料: ```python result = df[df["score"].isna()] ``` 結果: ```text name age city score date 4 Eva 22 Taipei NaN 2024-05-12 ``` 篩選分數不缺失的資料: ```python result = df[df["score"].notna()] ``` 也可以使用: ```python df[df["score"].isnull()] # 等同於 isna() df[df["score"].notnull()] # 等同於 notna() ``` 不要使用: ```python df[df["score"] == np.nan] ``` 因為 `NaN` 不等於任何值,包括它自己。應使用 `isna()`。 --- ## 7. 日期篩選 由於 `date` 欄位已經是日期型別,可以直接比較: ```python result = df[df["date"] >= "2024-03-01"] ``` 篩選日期區間: ```python result = df[ (df["date"] >= "2024-02-01") & (df["date"] <= "2024-04-30") ] ``` 也可以使用 `between()`: ```python result = df[ df["date"].between("2024-02-01", "2024-04-30") ] ``` ### 篩選特定年份或月份 ```python df[df["date"].dt.year == 2024] df[df["date"].dt.month == 3] df[df["date"].dt.day == 20] ``` ### 日期欄位不是日期型別時 讀取資料後,先轉換: ```python df["date"] = pd.to_datetime(df["date"], errors="coerce") ``` `errors="coerce"` 會將無法解析的值轉成 `NaT`。 --- ## 8. 使用 `.loc[]` 過濾列與欄位 以下篩選年齡大於 25 的資料,並只取 `name`、`age`、`score` 三欄: ```python result = df.loc[ df["age"] > 25, ["name", "age", "score"] ] ``` 這是非常推薦的寫法,因為可以同時指定: 1. 哪些列 2. 哪些欄位 語法: ```python df.loc[列條件, 欄位名稱] ``` 例如: ```python df.loc[df["city"] == "Taipei", "name"] ``` 只取得 Taipei 的姓名。 同時修改過濾後的資料: ```python df.loc[df["score"] < 70, "score"] = 70 ``` 這會把分數低於 70 的值改成 70。 --- ## 9. 使用 `.query()` 篩選 `query()` 可以讓條件更接近自然語言: ```python result = df.query("age > 25 and score >= 80") ``` 篩選城市: ```python result = df.query("city == 'Taipei'") ``` 多個城市: ```python result = df.query("city in ['Taipei', 'Taichung']") ``` 使用外部變數時,要加上 `@`: ```python min_age = 25 result = df.query("age >= @min_age") ``` 也可以搭配日期: ```python start_date = "2024-02-01" result = df.query("date >= @start_date") ``` ### `query()` 的優點 ```python df.query("age > 25 and city == 'Taipei'") ``` 通常比以下寫法更容易閱讀: ```python df[(df["age"] > 25) & (df["city"] == "Taipei")] ``` ### `query()` 的限制 欄位名稱若包含空格或特殊字元,需要使用反引號: ```python df.query("`customer name` == 'Alice'") ``` --- ## 10. 過濾後重新設定索引 過濾後,原本的索引通常會保留: ```python result = df[df["age"] > 25] print(result.index) ``` 結果可能是: ```text Index([1, 2, 3], dtype='int64') ``` 如果希望索引重新從 0 開始: ```python result = df[df["age"] > 25].reset_index(drop=True) ``` `drop=True` 表示不要將舊索引保留成新欄位。 --- ## 11. 過濾後修改資料與 `SettingWithCopyWarning` 以下寫法可能產生警告: ```python result = df[df["age"] > 25] result["group"] = "adult" ``` 建議使用 `.loc[]` 或 `.copy()`: ```python result = df.loc[df["age"] > 25].copy() result["group"] = "adult" ``` 如果要直接修改原始 `df`: ```python df.loc[df["age"] > 25, "group"] = "adult" ``` ### 建議原則 - 只想取得資料:可以直接過濾 - 過濾後還要修改:使用 `.copy()` - 想修改原始資料:使用 `.loc[]` --- ## 12. 複合範例 篩選: - 城市為 Taipei 或 Taichung - 年齡至少 25 歲 - 分數不為缺失值 - 分數至少 80 ```python result = df.loc[ df["city"].isin(["Taipei", "Taichung"]) & (df["age"] >= 25) & df["score"].notna() & (df["score"] >= 80), ["name", "age", "city", "score"] ] print(result) ``` 結果: ```text name age city score 0 Alice 25 Taipei 88.0 2 Charlie 28 Taipei 92.0 ``` 用 `query()` 表示: ```python result = df.query( "city in ['Taipei', 'Taichung'] " "and age >= 25 " "and score >= 80" ) ``` --- ## 13. 讀取 CSV 後直接過濾 實務上通常是讀取 CSV,再進行篩選: ```python df = pd.read_csv("sales.csv") result = df.loc[ (df["amount"] > 1000) & (df["status"] == "completed") ] ``` 如果資料量很大,也可以在讀取時只選取需要的欄位: ```python df = pd.read_csv( "sales.csv", usecols=["customer", "amount", "status"] ) ``` 這可以減少記憶體使用量。 --- ## 14. 過濾技巧整理 ### 技巧一:先確認欄位型別 ```python print(df.dtypes) ``` 例如日期欄位若是 `object`,應先轉換: ```python df["date"] = pd.to_datetime(df["date"]) ``` ### 技巧二:查看條件結果 可以先將條件存成變數,方便除錯: ```python condition = ( (df["age"] >= 25) & (df["score"] >= 80) ) print(condition) result = df[condition] ``` ### 技巧三:使用 `value_counts()` 了解資料內容 ```python print(df["city"].value_counts()) ``` 這有助於確認實際資料中有哪些分類值。 ### 技巧四:注意字串空白 如果資料可能有前後空白: ```python df["city"] = df["city"].str.strip() ``` 再進行篩選: ```python df[df["city"] == "Taipei"] ``` ### 技巧五:欄位名稱包含空格時 使用 `.loc[]`: ```python df.loc[df["customer name"] == "Alice"] ``` 或在 `query()` 中使用反引號: ```python df.query("`customer name` == 'Alice'") ``` --- ## 15. 常見錯誤總結 ### 錯誤一:使用 `and`、`or` ```python # 錯誤 df[(df["age"] > 20) and (df["score"] > 80)] ``` ```python # 正確 df[(df["age"] > 20) & (df["score"] > 80)] ``` ### 錯誤二:多條件沒有括號 ```python # 錯誤 df[df["age"] > 20 & df["score"] > 80] ``` ```python # 正確 df[(df["age"] > 20) & (df["score"] > 80)] ``` ### 錯誤三:用 `== np.nan` ```python # 錯誤 df[df["score"] == np.nan] ``` ```python # 正確 df[df["score"].isna()] ``` ### 錯誤四:修改過濾結果時出現警告 ```python # 建議 result = df.loc[df["age"] > 25].copy() result["category"] = "adult" ``` --- ## 最常用的寫法速查 ```python # 單一條件 df[df["age"] > 30] # AND df[(df["age"] > 25) & (df["score"] >= 80)] # OR df[(df["city"] == "Taipei") | (df["city"] == "Taichung")] # NOT df[df["city"] != "Taipei"] # 多個值 df[df["city"].isin(["Taipei", "Kaohsiung"])] # 範圍 df[df["age"].between(20, 30)] # 字串包含 df[df["name"].str.contains("a", case=False, na=False)] # 缺失值 df[df["score"].isna()] # 非缺失值 df[df["score"].notna()] # 日期 df[df["date"] >= "2024-03-01"] # 過濾列與欄位 df.loc[df["age"] > 25, ["name", "age"]] # query df.query("age > 25 and score >= 80") # 過濾後重設索引 df[df["age"] > 25].reset_index(drop=True) ``` 實務上,最推薦優先掌握: 1. `df[條件]` 2. `df.loc[條件, 欄位]` 3. `isin()` 4. `between()` 5. `str.contains()` 6. `isna()` / `notna()` 7. `query()`
相關學習地圖、教學課程
Python 資料工程
從 0 開始,成為資料工程師的學習路徑。