# 導入相關庫 import numpy as np import pandas as pd
在數據處理過程中,經常會遇到要篩選不同要求的數據。通過 Pandas 可以輕松時間,這一篇我們來看下如何使用 Pandas 來完成數據篩選吧
創建數據
index = pd.Index(data=["Tom", "Bob", "Mary", "James", "Andy", "Alice"], name="name") data = { "age": [18, 30, np.nan, 40, np.nan, 30], "city": ["Bei Jing ", "Shang Hai ", "Guang Zhou", "Shen Zhen", np.nan, " "], "sex": [None, "male", "female", "male", np.nan, "unknown"], "birth": ["2000-02-10", "1988-10-17", None, "1978-08-08", np.nan, "1988-10-17"] } user_info = pd.DataFrame(data=data, index=index) # 將出生日期轉為時間戳 user_info["birth"] = pd.to_datetime(user_info.birth) user_info """ age city sex birth name Tom 18.0 Bei Jing None 2000-02-10 Bob 30.0 Shang Hai male 1988-10-17 Mary NaN Guang Zhou female NaT James 40.0 Shen Zhen male 1978-08-08 Andy NaN NaN NaN NaT Alice 30.0 unknown 1988-10-17 """
Pandas 中除了支持 Python 和 Numpy 的索引運算符[]和屬性運算符.來訪問數據之外,還有很多其他的方式來訪問數據,我們一起來看看吧
字典式 get 訪問
我們知道,Python 中的字典要獲取 value 時可以通過 get 方法來獲取,對於 Series 和 DataFrame 也一樣,他們一樣可以通過 get 方法來獲取
# 獲取得到所有年齡相關的這一列的信息,結果為一個 Series user_info.get("age") # 從包含所有的年齡信息的 Series 中得到 Tom 的年齡 user_info.get("age").get("Tom")
屬性訪問
除了可以通過 get 方法來獲取數據之外,還可以通過屬性的方式來訪問,同樣完成上面的功能, 來看下如何通過屬性訪問的方式來實現
# 獲取得到所有年齡相關的這一列的信息,結果為一個 Series user_info.age # 從包含所有的年齡信息的 Series 中得到 Tom 的年齡 user_info.age.Tom
切片操作
在學習 Python 時,會發現列表的切片操作非常地方便,Series 和 DataFrame 同樣也有切片操作
對於 Series 來說,通過切片可以完成選擇指定的行,對於 DataFrame 來說,通過切片可以完成選擇指定的行或者列,來看看怎么玩吧
# 篩選行 # 獲取年齡的前兩行 user_info.age[:2] # 獲取所有信息的前兩行 user_info[:2] # 所有信息每兩行選擇一次數據 user_info[::2] # 對所有信息進行反轉 user_info[::-1] # 篩選 DataFrame 中的列 # 篩選出一列數據:將列名傳入切片即可完成篩選 user_info["age"] # 篩選出多列的數據:將對應的列名傳入組成一個列表,傳入切片中即可 user_info[["city", "age"]]
可以看到,列表中的列名的順序會影響最后的結果
通過數字篩選行和列
通過切片操作可以完成篩選行或者列,如何同時篩選出行和列呢?通過 iloc 即可實現, iloc 支持傳入行和列的篩選器,並用 , 隔開。無論是行或列篩選器, 都可以為以下幾種情況:
- 一個整數,如 2
- 一個整數列表,如 [2, 1, 4]
- 一個整數切片對象,如 2:4
- 一個布爾數組
- 一個callable
先來看下前3種的用法
# 篩選出第一行數據 user_info.iloc[0] # 篩選出第二行第一列的數據 user_info.iloc[1, 0] # 篩選出第二行、第一行、第三行對應的第一列的數據 user_info.iloc[[1, 0, 2], 0] # 篩選出第一行至第三行以及第一列至第二列的數據 user_info.iloc[0:3, 0:2] # 篩選出第一列至第二列的數據 user_info.iloc[:, 0:2]
通過名稱篩選行和列
雖然通過 iloc 可以實現同時篩選出行和列,但是它接收的是數字,非常不直觀, 通過 loc 可實現傳入名稱來篩選數據, loc 支持傳入行和列的篩選器,並用 , 隔開。無論是行或者列篩選器,都可以為以下幾種情況:
- 一個索引的名稱,如:"Tom"
- 一個索引的列表,如:["Bob", "Tom"]
- 一個標簽范圍,如:"Tom": "Mary"
- 一個布爾數組
- 一個callable
先來看下前3種的用法
# 篩選出索引名稱為 Tom 的數據一行數據 user_info.loc["Tom"] # 篩選出索引名稱為 Tom 的年齡 user_info.loc["Tom", "age"] # 篩選出索引名稱在 ["Bob", "Tom"] 中的兩行數據 user_info.loc[["Bob", "Tom"]] # 篩選出索引名稱在 Tom 到 Mary 之間的數據 user_info.loc["Tom": "Mary"] # 篩選出年齡這一列數據 user_info.loc[:, ["age"]] # 篩選出所有 age 到 birth 之間的這幾列數據 user_info.loc[:, "age": "birth"]
布爾索引
通過布爾操作我們一樣可以進行篩選操作,布爾操作時
- & --> and
- | --> or
- ~ --> not
當有多個布爾表達式時,需要通過小括號來進行分組
# 篩選出年齡>20的數據 user_info[user_info.age > 20] # 篩選出年齡在20歲以上,並且性別為男性的數據 user_info[(user_info.age > 20) & (user_info.sex == "male")] # 篩選出性別不為 unknown 的數據 user_info[~(user_info.sex == "unknown")] # 篩選出年齡>20,只顯示age字段的數據 user_info.loc[user_info.age > 20, ["age"]]
isin 篩選
Series 包含了 isin 方法,它能夠返回一個布爾向量,用於篩選數據
# 篩選出性別屬於 male 和 female的數據 user_info[user_info.sex.isin(["male", "female"])] # 篩選出索引為Bob的數據 user_info[user_info.index.isin(["Bob"])]
Callable 篩選
loc、iloc、切片操作都支持接收一個 callable 函數,callable 必須是帶有一個參數(調用Series,DataFrame)的函數,並且返回用於索引的有效輸出
# 篩選age>20的數據 user_info[lambda df: df["age"] > 20] # 篩選age>20,返回age字段的數據 user_info.loc[lambda df: df.age > 20, lambda df: ["age"]] # 篩選行索引為0和5,列索引為0的數據 user_info.iloc[lambda df: [0, 5], lambda df: [0]]