Pandas的數(shù)據(jù)過濾實現(xiàn)
作者|Amanda Iglesias Moreno 編譯|VK 來源|Towards Datas Science
從數(shù)據(jù)幀中過濾數(shù)據(jù)是清理數(shù)據(jù)時最常見的操作之一。Pandas提供了一系列根據(jù)行和列的位置和標簽選擇數(shù)據(jù)的方法。此外,Pandas還允許你根據(jù)列類型獲取數(shù)據(jù)子集,并使用布爾索引篩選行。
在本文中,我們將介紹從Pandas數(shù)據(jù)框中選擇數(shù)據(jù)子集的最常見操作:
- 按標簽選擇單列
- 按標簽選擇多列
- 按數(shù)據(jù)類型選擇列
- 按標簽選擇一行
- 按標簽選擇多行
- 按位置選擇一行
- 按位置選擇多行
- 同時選擇行和列
- 選擇標量值
- 使用布爾選擇選擇選擇行
數(shù)據(jù)集
在本文中,我們使用一個小數(shù)據(jù)集進行學(xué)習(xí)。在現(xiàn)實世界中,所使用的數(shù)據(jù)集要大得多;然而,用于過濾數(shù)據(jù)的過程保持不變。
數(shù)據(jù)框包含公司10名員工的信息:(1)身份證,(2)姓名,(3)姓氏,(4)部門,(5)電話,(6)工資,(7)合同類型。
import pandas as pd # 員工的信息 id_number = ['128', '478', '257', '299', '175', '328', '099', '457', '144', '222'] name = ['Patrick', 'Amanda', 'Antonella', 'Eduard', 'John', 'Alejandra', 'Layton', 'Melanie', 'David', 'Lewis'] surname = ['Miller', 'Torres', 'Brown', 'Iglesias', 'Wright', 'Campos', 'Platt', 'Cavill', 'Lange', 'Bellow'] division = ['Sales', 'IT', 'IT', 'Sales', 'Marketing', 'Engineering', 'Engineering', 'Sales', 'Engineering', 'Sales'] salary = [30000, 54000, 80000, 79000, 15000, 18000, 30000, 35000, 45000, 30500] telephone = ['7366578', '7366444', '7366120', '7366574', '7366113', '7366117', '7366777', '7366579', '7366441', '7366440'] type_contract = ['permanent', 'temporary', 'temporary', 'permanent', 'internship', 'internship', 'permanent', 'temporary', 'permanent', 'permanent'] # 包含員工信息的dataframe df_employees = pd.DataFrame({'name': name, 'surname': surname, 'division': division, 'salary': salary, 'telephone': telephone, 'type_contract': type_contract}, index=id_number) df_employees
1.按標簽選擇單列
要在Pandas中選擇一個列,我們可以使用.運算符和[]運算符。
按標簽選擇單列
df[string]
下面的代碼使用這兩種方法訪問salary列。
# 使用.符號選擇列(salary) salary = df_employees.salary # 使用方括號選擇列(salary) salary_2 = df_employees['salary'] # 當選擇單個列時,我們獲得一個Series對象 print(type(salary)) # <class 'pandas.core.series.Series'> print(type(salary_2)) # <class 'pandas.core.series.Series'> salary
如上所示,當檢索單個列時,結(jié)果是一個Series對象。為了在只選擇一列時獲得一個DataFrame對象,我們需要傳入一個列表,而不僅僅是一個字符串。
# 通過向索引操作符傳遞一個字符串來獲取一個Series對象 df_employees['salary'] # 通過將帶有單個項的列表傳遞給索引操作符來獲取DataFrame對象 df_employees[['salary']]
此外,重要的是要記住,當列名包含空格時,我們不能使用.表示法來訪問數(shù)據(jù)幀的特定列。如果我們這么做了,就會產(chǎn)生一個語法錯誤。
2.按標簽選擇多列
我們可以通過傳入一個列名稱如下的列表來選擇一個數(shù)據(jù)幀的多個列。
按標簽選擇多列
df[list_of_strings]
# 通過將包含列名的列表傳遞給索引操作符來選擇多個列 df_employees[['division', 'salary']]
如上所示,結(jié)果是一個DataFrame對象,只包含列表中提供的列。
3.按數(shù)據(jù)類型選擇列
我們可以使用pandas.DataFrame.select類型(include=None,exclude=None)根據(jù)列的數(shù)據(jù)類型選擇列。該方法接受參數(shù)include和exclude中的列表或單個數(shù)據(jù)類型。
請記住,必須至少提供其中一個參數(shù)(include或exclude),并且它們不能包含重疊的元素。
按數(shù)據(jù)類型選擇列
df.select_dtypes(include=None, exclude=None)
在下面的示例中,我們通過傳入np.number對象添加到include參數(shù)。或者,我們可以通過提供字符串'number'作為輸入來獲得相同的結(jié)果。
可以看到,select_dtypes()方法返回一個DataFrame對象,該對象包括include參數(shù)中的數(shù)據(jù)類型,而排除exclude參數(shù)中的數(shù)據(jù)類型。
import numpy as np # 選擇數(shù)值列- numpy對象 numeric_inputs = df_employees.select_dtypes(include=np.number) # 使用.columns屬性 numeric_inputs.columns # Index(['salary'], dtype='object') # 該方法返回一個DataFrame對象 print(type(numeric_inputs)) # <class 'pandas.core.frame.DataFrame'> # 選擇數(shù)字列 numeric_inputs_2 = df_employees.select_dtypes(include='number') # 使用.columns屬性 numeric_inputs_2.columns # Index(['salary'], dtype='object') # 該方法返回一個DataFrame對象 print(type(numeric_inputs_2)) # <class 'pandas.core.frame.DataFrame'> # 可視化數(shù)據(jù)框 numeric_inputs
如前所述,select_dtypes()方法可以同時接受字符串和numpy對象作為輸入。下表顯示了在Pandas中引用數(shù)據(jù)類型的最常用方法。
作為提醒,我們可以使用pandas.DataFrame.info方法或使用pandas.DataFrame.dtypes屬性。前者打印數(shù)據(jù)幀的簡明摘要,包括列名及其數(shù)據(jù)類型,而后者返回一個包含每個列的數(shù)據(jù)類型的序列。
# 數(shù)據(jù)框架的簡要摘要,包括列名及其數(shù)據(jù)類型 df_employees.info()
# 檢查列的數(shù)據(jù)類型 df_employees.dtypes
4.按標簽選擇單行
數(shù)據(jù)幀和序列不一定有數(shù)字索引。默認情況下,索引是表示行位置的整數(shù);但是,它也可以是字母數(shù)字字符串。在我們當前的示例中,索引是員工的id號。
# 我們可以使用.index方法檢查數(shù)據(jù)幀的索引 df_employees.index # Index(['128', '478', '257', '299', '175', '328', '099', '457', '144', '222'], dtype='object') # 索引是雇員的id號。
要按id號選擇一行,我們可以使用.loc[]索引器提供一個字符串(索引名)作為輸入。
按標簽選擇單行
df.loc[string]
下面的代碼顯示如何選擇id號為478的員工。
# 使用.loc[]索引器選擇id號為478的員工 df_employees.loc['478']
如上所示,當選中一行時,.loc[]索引器將返回一個Series對象。但是,我們也可以通過將單個元素列表傳遞給.loc[]方法來獲得單行數(shù)據(jù)幀,如下所示。
# 使用.loc[]索引器選擇id號為478的雇員,并提供一個單元素列表 df_employees.loc[['478']]
5.按標簽選擇多行
我們可以使用.loc[]索引器選擇多行。除單個標簽外,索引器還接受一個列表或標簽片段作為輸入。
按標簽選擇多行
df.loc[list_of_strings] df.loc[slice_of_strings]
接下來,我們獲得包含id號為478和222的雇員的數(shù)據(jù)幀的子集,如下所示。
# 使用.loc[]索引器選擇id號為478和222的員工 df_employees.loc[['478', '222']]
請注意,始終包含.loc[]方法的結(jié)束索引,這意味著所選內(nèi)容包括最后一個標簽。
6.按位置選擇單行
iloc[]索引器用于按位置索引數(shù)據(jù)幀。要使用.iloc[]屬性選擇單行,我們將行位置(單個整數(shù))傳遞給索引器。
按位置選擇單行
df.iloc[integer]
在下面的代碼塊中,我們選擇索引為0的行。在這種情況下,返回數(shù)據(jù)幀的第一行,因為在Pandas中索引從0開始。
# 選擇數(shù)據(jù)幀的第一行 df_employees.iloc[0]
此外,.iloc[]索引器還支持負整數(shù)(從-1開始)作為相對于數(shù)據(jù)幀末尾的相對位置。
# 選擇數(shù)據(jù)幀的最后一行 df_employees.iloc[-1]
如上所示,當選擇一行時,.iloc[]索引器返回一個以列名作為索引的Series對象。但是,正如我們對.loc[]索引器所做的那樣,我們還可以通過以下方式將單個整數(shù)列表傳遞給索引器來獲取數(shù)據(jù)幀。
# 選擇數(shù)據(jù)幀的最后一行 df_employees.iloc[[-1]]
最后,請記住,在嘗試訪問超出邊界的索引時會引發(fā)索引器錯誤。
# 數(shù)據(jù)框的形狀- 10行6列 df_employees.shape # (10, 6) # 當試圖訪問一個越界的索引時,會引發(fā)一個IndexError df_employees.iloc[10] # IndexError
7.通過多個位置選擇
為了按位置提取多行,我們將list或slice對象傳遞給.iloc[]索引器。
按位置選擇多行
df.iloc[list_of_integers] df.iloc[slice_of_integers]
下面的代碼塊演示如何使用整數(shù)列表選擇數(shù)據(jù)幀的前五行。
# 使用列表選擇dataframe的前5行 df_employees.iloc[[0, 1, 2, 3, 4]]v
或者,我們可以使用切片表示法得到相同的結(jié)果。
# 使用切片選擇dataframe的前5行 df_employees.iloc[0:5]
如上所示,Python切片規(guī)則(半開區(qū)間)適用于.iloc[]屬性,這意味著包含第一個索引,但不包括結(jié)束索引。
8.同時選擇行和列
到目前為止,我們已經(jīng)學(xué)習(xí)了如何使用.loc[]和.iloc[]索引器按標簽或位置選擇數(shù)據(jù)幀中的行。但是,這兩個索引器不僅能夠同時選擇行,還可以同時選擇行和列。
為此,我們必須提供用逗號分隔的行和列標簽/位置,如下所示:
同時選擇行和列
df.loc[row_labels, column_labels] df.iloc[row_positions, column_positions]
其中行標簽和列標簽可以是單個字符串、字符串列表或字符串片段。同樣,行位置和列位置可以是單個整數(shù)、整數(shù)列表或整數(shù)切片。
下面的示例演示如何使用.loc[]和.iloc[]索引器同時提取行和列。
選擇標量值
我們選擇id為478的員工的工資,方法如下。
# 按位置選擇身份證號為478的員工的工資 df_employees.iloc[1, 3] # 根據(jù)標簽選擇id號為478的員工的工資 df_employees.loc['478', 'salary'] # 54000
在本例中,兩個索引器的輸出都是整數(shù)。
選擇單行和多列
我們選擇id號為478的員工的姓名、姓氏和薪水,方法是將一個值作為第一個參數(shù),將一個值列表作為第二個參數(shù),從而獲得一個Series對象。
# 按職位選擇身份證號為478的員工的姓名、姓氏和工資 df_employees.iloc[1, [0, 1, 3]] # 通過標簽選擇身份證號為478的員工的姓名、姓氏和工資 df_employees.loc['478', ['name', 'surname', 'salary']]
選擇不相交的行和列
要選擇多行和多列,我們需要向兩個索引器傳遞兩個值列表。下面的代碼顯示如何提取id號為478和222的員工的姓名、姓氏和工資。
# 按職位選擇身份證號為478和222的員工的姓名、姓氏和工資 df_employees.iloc[[1, 9], [0, 1, 3]] # 根據(jù)標簽選擇身份證號為478和222的員工的姓名、姓氏和工資 df_employees.loc[['478', '222'], ['name', 'surname', 'salary']]
與以前不同,這兩個索引器的輸出都是一個DataFrame對象。
選擇連續(xù)的行和列
我們可以使用切片表示法提取數(shù)據(jù)幀的連續(xù)行和列。下面的代碼片段顯示如何選擇id號為128、478、257和299的員工的姓名、姓氏和薪水。
# 按職位選擇id號為128、478、257、299的員工的姓名、姓氏和工資 df_employees.iloc[:4, [0, 1, 3]] # 按標簽選擇id號為128、478、257、299的員工的姓名、姓氏和工資 df_employees.loc[:'299', ['name', 'surname', 'salary']]
如上所示,我們只使用切片表示法來提取數(shù)據(jù)幀的行,因為我們要選擇的id號是連續(xù)的(索引從0到3)。
一定要記住.loc[]索引器使用一個閉合的間隔,同時提取開始標簽和停止標簽。相反,.iloc[]索引器使用半開區(qū)間,因此不包括停止索引處的值。
9.使用.at[]和.iat[]索引器選擇標量值
如上所述,我們可以通過將兩個用逗號分隔的字符串/整數(shù)傳遞給.loc[]和.iloc[]索引器來選擇標量值。此外,Pandas還提供了兩個優(yōu)化函數(shù)來從數(shù)據(jù)幀對象中提取標量值:.at[]和.iat[]運算符。前者通過標簽提取單個值,而后者通過位置訪問單個值。
通過標簽和位置選擇標量值
df.at[string, string] df.iat[integer, integer]
下面的代碼顯示如何使用.at[]和.iat[]索引器按標簽和位置選擇id號為478的員工的工資。
# 按位置選擇身份證號為478的員工的工資 df_employees.iat[1, 3] # 根據(jù)標簽選擇id號為478的員工的工資 df_employees.at['478', 'salary'] # 54000
我們可以使用%timeit magic函數(shù)來計算這兩個Python語句的執(zhí)行時間。如下所示,.at[]和.iat[]運算符比.loc[]和.iloc[]索引器快得多。
# loc索引器的執(zhí)行時間 %timeit df_employees.loc['478', 'salary'] # at索引器的執(zhí)行時間 %timeit df_employees.at['478', 'salary']
# iloc索引器的執(zhí)行時間 %timeit df_employees.iloc[1, 3] # iat索引器的執(zhí)行時間 %timeit df_employees.iat[1, 3]
最后,必須記住,.at[]和.iat[]索引器只能用于訪問單個值,在嘗試選擇數(shù)據(jù)幀的多個元素時會引發(fā)類型錯誤。
# 當嘗試選擇多個元素時,會引發(fā)異常 df_employees.at['478', ['name', 'surname', 'salary']] # TypeError
10.使用布爾選擇行
到目前為止,我們已經(jīng)根據(jù)標簽和位置過濾了數(shù)據(jù)幀中的行和列?;蛘撸覀円部梢杂貌紶査饕赑andas中選擇一個子集。布爾選擇包括通過為每一行提供布爾值(True或False)來選擇數(shù)據(jù)幀的行。
在大多數(shù)情況下,這個布爾數(shù)組是通過將一個條件應(yīng)用于一個或多個列的值來計算的,該條件的計算結(jié)果為True或False,具體取決于這些值是否滿足條件。但是,也可以使用其他序列、Numpy數(shù)組、列表或Pandas系列手動創(chuàng)建布爾數(shù)組。
然后,布爾值序列放在方括號[]內(nèi),返回與真值相關(guān)聯(lián)的行。
使用布爾選擇選擇選擇行
df[sequence_of_booleans]
根據(jù)單列值的布爾選擇
根據(jù)單列值過濾數(shù)據(jù)幀的最常見方法是使用比較運算符。
比較運算符計算兩個操作數(shù)(A和b)之間的關(guān)系,并根據(jù)是否滿足條件返回True或False。下表包含Python中可用的比較運算符。
這些比較運算符可用于數(shù)據(jù)幀的單列,以獲得布爾值序列。例如,我們使用大于運算符確定員工的工資是否大于45000,如下所示。
# 工資超過45000的員工 df_employees['salary'] > 45000 1
輸出是一系列布爾函數(shù),其中工資高于45000為真,低于或等于45000為假。正如你可能注意到的那樣,boolean系列具有與原始數(shù)據(jù)幀相同的索引(id編號)。
可以將此序列傳遞給索引運算符[],以僅返回結(jié)果為True的行。
# 選擇工資高于45000的員工 df_employees[df_employees['salary'] > 45000]
如上所示,我們獲得了一個數(shù)據(jù)幀對象,其中只包含工資高于45000的員工。
根據(jù)多列值的布爾選擇
之前,我們已經(jīng)根據(jù)一個條件過濾了一個數(shù)據(jù)幀。但是,我們也可以使用邏輯運算符將多個布爾表達式組合在一起。
在Python中,有三個邏輯運算符:and、or和not。但是,這些關(guān)鍵字在Pandas中不可用于組合多個布爾條件。而是使用以下運算符。
下面的代碼展示了如何選擇薪水高于45000的員工,以及有一份永久合同,其中包含兩個布爾表達式和邏輯運算符&。
# 選擇工資高于45000并有長期合同的員工 df_employees[(df_employees['salary'] > 45000) & (df_employees['type_contract'] == 'permanent')]
如你所知,在Python中,比較運算符的優(yōu)先級高于邏輯運算符。但是,它不適用于邏輯運算符優(yōu)先于比較運算符的panda。因此,我們需要將每個布爾表達式包裝在括號中以避免錯誤。
使用Pandas方法的布爾選擇
Pandas提供了一系列返回布爾值序列的內(nèi)置函數(shù),它是結(jié)合比較運算符和邏輯運算符的更復(fù)雜布爾表達式的一個有吸引力的替代方案。
isin方法
這個pandas.Series.isin方法接受一系列值,并在序列中與列表中的值匹配的位置返回True。
此方法允許我們檢查列中是否存在一個或多個元素,而無需使用邏輯運算符或。下面的代碼顯示如何使用邏輯運算符or和isin方法選擇具有永久或臨時合同的員工。
# 使用邏輯操作符或選擇具有永久或臨時合同的員工 df_employees[(df_employees['type_contract'] == 'temporary') | (df_employees['type_contract'] == 'permanent')] # 使用isin方法選擇有永久或臨時合同的員工 df_employees[df_employees['type_contract'].isin(['temporary', 'permanent'])]
如你所見,isin方法在檢查同一列中的多個或條件時非常方便。另外,它更快!
# 使用邏輯運算符|執(zhí)行時間 %timeit df_employees[(df_employees['type_contract'] == 'temporary') | (df_employees['type_contract'] == 'permanent')] # isin方法的執(zhí)行時間 %timeit df_employees[df_employees['type_contract'].isin(['temporary', 'permanent'])]
between方法
這個熊貓系列方法接受兩個用逗號分隔的標量,它們表示一個值范圍的上下邊界,并在該范圍內(nèi)的位置返回True。
以下代碼選擇工資高于或等于30000且小于或等于80000的員工。
# 薪資高于或等于30000,低于或等于80000的員工 df_employees[df_employees['salary'].between(30000, 80000)]
如你所見,這兩個邊界(30000和80000)都包括在內(nèi)。要排除它們,我們必須按以下方式傳遞inclusive=False參數(shù)。
# 薪資在3萬以上,8萬以下的員工 df_employees[df_employees['salary'].between(30000, 80000, inclusive=False)]
正如你可能注意到的,上面的代碼相當于編寫兩個布爾表達式,并使用邏輯運算符and對它們求值。
# 薪資高于或等于30000,低于或等于80000的員工 df_employees[(df_employees['salary']>=30000) & (df_employees['salary']<=80000)]
字符串方法
此外,我們還可以將布爾索引與字符串方法一起使用,只要它們返回布爾值序列。
例如pandas.Series.str.contains方法檢查列的所有元素中是否存在子字符串,并返回一系列布爾值,我們可以將這些布爾值傳遞給索引運算符以篩選數(shù)據(jù)幀。
下面的代碼顯示如何選擇包含57的所有電話號碼。
# 選擇所有包含57的電話號碼 df_employees[df_employees['telephone'].str.contains('57')]
當contains方法計算子字符串是否包含在序列的每個元素中。pandas.Series.str.startswith函數(shù)檢查字符串開頭是否存在子字符串。同樣地pandas.Series.str.endswith測試字符串末尾是否存在子字符串。
以下代碼顯示如何選擇姓名以“A”開頭的員工。
# 選擇名字以“A”開頭的員工 df_employees[df_employees['name'].str.startswith('A')]
摘要
在本文中,我們學(xué)習(xí)從Dataframe中選擇子集。此外,我們還提供了多個使用示例?,F(xiàn)在!現(xiàn)在是時候在清理你自己的數(shù)據(jù)時應(yīng)用這些技術(shù)了!
到此這篇關(guān)于Pandas的數(shù)據(jù)過濾實現(xiàn)的文章就介紹到這了,更多相關(guān)Pandas 數(shù)據(jù)過濾內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python tkinter之ComboBox(下拉框)的使用簡介
這篇文章主要介紹了Python tkinter之ComboBox(下拉框)的使用簡介,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2021-02-02python3批量刪除豆瓣分組下的好友的實現(xiàn)代碼
下面小編就為大家?guī)硪黄猵ython3批量刪除豆瓣分組下的好友的實現(xiàn)代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-06-06tensorflow 1.X遷移至tensorflow2 的代碼寫法
本文主要介紹了tensorflow 1.X遷移至tensorflow2 的代碼寫法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12用Python的Flask框架結(jié)合MySQL寫一個內(nèi)存監(jiān)控程序
這篇文章主要介紹了用Python的Flask框架結(jié)合MySQL些一個內(nèi)存監(jiān)控程序的例子,并且能將結(jié)果作簡單的圖形化顯示,需要的朋友可以參考下2015-11-11Python?hug庫構(gòu)建快速可擴展的Web API框架使用詳解
這篇文章主要介紹了Python?hug庫構(gòu)建快速可擴展的Web API框架使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-02-02