前2篇分別系統(tǒng)性介紹了numpy和matplotlib的入門基本知識,,今天本文自然是要對pandas進(jìn)行入門詳細(xì)介紹,,通過本文你將系統(tǒng)性了解pandas為何會有數(shù)據(jù)分析界'瑞士軍刀'的盛譽(yù)。 行文二級目錄
pandas,,python+data+analysis的組合縮寫,是python中基于numpy和matplotlib的第三方數(shù)據(jù)分析庫,,與后兩者共同構(gòu)成了python數(shù)據(jù)分析的基礎(chǔ)工具包,,享有數(shù)分三劍客之名。
正因?yàn)閜andas是在numpy基礎(chǔ)上實(shí)現(xiàn),,其核心數(shù)據(jù)結(jié)構(gòu)與numpy的ndarray十分相似,,但pandas與numpy的關(guān)系不是替代,,而是互為補(bǔ)充。二者之間主要區(qū)別是: pandas主要面向數(shù)據(jù)處理與分析,,主要具有以下功能特色:- 按索引匹配的廣播機(jī)制,這里的廣播機(jī)制與numpy廣播機(jī)制還有很大不同
- 便捷的數(shù)據(jù)讀寫操作,,相比于numpy僅支持?jǐn)?shù)字索引,,pandas的兩種數(shù)據(jù)結(jié)構(gòu)均支持標(biāo)簽索引,包括bool索引也是支持的
- 類比SQL的join和groupby功能,,pandas可以很容易實(shí)現(xiàn)SQL這兩個(gè)核心功能,,實(shí)際上,SQL的絕大部分DQL和DML操作在pandas中都可以實(shí)現(xiàn)
- 類比Excel的數(shù)據(jù)透視表功能,,Excel中最為強(qiáng)大的數(shù)據(jù)分析工具之一是數(shù)據(jù)透視表,,這在pandas中也可輕松實(shí)現(xiàn)
- 自帶正則表達(dá)式的字符串向量化操作,對pandas中的一列字符串進(jìn)行通函數(shù)操作,,而且自帶正則表達(dá)式的大部分接口
- 常用的數(shù)據(jù)分析與統(tǒng)計(jì)功能,,包括基本統(tǒng)計(jì)量、分組統(tǒng)計(jì)分析等
- 集成matplotlib的常用可視化接口,,無論是series還是dataframe,,均支持面向?qū)ο蟮睦L圖接口
正是由于具有這些強(qiáng)大的數(shù)據(jù)分析與處理能力,pandas還有數(shù)據(jù)處理中'瑞士軍刀'的美名。02 數(shù)據(jù)結(jié)構(gòu)pandas核心數(shù)據(jù)結(jié)構(gòu)有兩種,,即一維的series和二維的dataframe,二者可以分別看做是在numpy一維數(shù)組和二維數(shù)組的基礎(chǔ)上增加了相應(yīng)的標(biāo)簽信息,。正因如此,可以從兩個(gè)角度理解series和dataframe:series和dataframe分別是一維和二維數(shù)組,,因?yàn)槭菙?shù)組,,所以numpy中關(guān)于數(shù)組的用法基本可以直接應(yīng)用到這兩個(gè)數(shù)據(jù)結(jié)構(gòu),包括數(shù)據(jù)創(chuàng)建,、切片訪問,、通函數(shù)、廣播機(jī)制等 series是帶標(biāo)簽的一維數(shù)組,,所以還可以看做是類字典結(jié)構(gòu):標(biāo)簽是key,,取值是value;而dataframe則可以看做是嵌套字典結(jié)構(gòu),,其中列名是key,,每一列的series是value。所以從這個(gè)角度講,,pandas數(shù)據(jù)創(chuàng)建的一種靈活方式就是通過字典或者嵌套字典,,同時(shí)也自然衍生出了適用于series和dataframe的類似字典訪問的接口,即通過loc索引訪問,。
注意,,這里強(qiáng)調(diào)series和dataframe是一個(gè)類字典結(jié)構(gòu)而非真正意義上的字典,原因在于series中允許標(biāo)簽名重復(fù),、dataframe中則允許列名和標(biāo)簽名均有重復(fù),,而這是一個(gè)真正字典所不允許的。
考慮series和dataframe兼具numpy數(shù)組和字典的特性,,那么就不難理解二者的以下屬性:ndim/shape/dtypes/size/T,,分別表示了數(shù)據(jù)的維數(shù)、形狀,、數(shù)據(jù)類型和元素個(gè)數(shù)以及轉(zhuǎn)置結(jié)果,。其中,由于pandas允許數(shù)據(jù)類型是異構(gòu)的,,各列之間可能含有多種不同的數(shù)據(jù)類型,,所以dtype取其復(fù)數(shù)形式dtypes。與此同時(shí),,series因?yàn)橹挥幸涣?,所以?shù)據(jù)類型自然也就只有一種,,pandas為了兼容二者,series的數(shù)據(jù)類型屬性既可以用dtype也可以用dtypes獲??;而dataframe則只能用dtypes。
index/columns/values,,分別對應(yīng)了行標(biāo)簽,、列標(biāo)簽和數(shù)據(jù),其中數(shù)據(jù)就是一個(gè)格式向上兼容所有列數(shù)據(jù)類型的array,。為了沿襲字典中的訪問習(xí)慣,,還可以用keys()訪問標(biāo)簽信息,在series返回index標(biāo)簽,,在dataframe中則返回columns列名,;可以用items()訪問鍵值對,但一般用處不大,。
這里提到了index和columns分別代表行標(biāo)簽和列標(biāo)簽,,就不得不提到pandas中的另一個(gè)數(shù)據(jù)結(jié)構(gòu):Index,例如series中標(biāo)簽列,、dataframe中行標(biāo)簽和列標(biāo)簽均屬于這種數(shù)據(jù)結(jié)構(gòu),。既然是數(shù)據(jù)結(jié)構(gòu),就必然有數(shù)據(jù)類型dtype屬性,,例如數(shù)值型,、字符串型或時(shí)間類型等,其類型絕大多數(shù)場合并不是我們關(guān)注的主體,,但有些時(shí)候值得注意,,如后文中提到的通過[ ]執(zhí)行標(biāo)簽切片訪問行的過程。此外,,index數(shù)據(jù)結(jié)構(gòu)還有名字屬性name(默認(rèn)為None),、形狀屬性shape等。
關(guān)于series和dataframe數(shù)據(jù)結(jié)構(gòu)本身,,有大量的方法可用于重構(gòu)結(jié)構(gòu)信息: rename,,可以對標(biāo)簽名重命名,也可以重置index和columns的部分標(biāo)簽列信息,,接收標(biāo)量(用于對標(biāo)簽名重命名)或字典(用于重命名行標(biāo)簽和列標(biāo)簽)
reindex,,接收一個(gè)新的序列與已有標(biāo)簽列匹配,當(dāng)原標(biāo)簽列中不存在相應(yīng)信息時(shí),,填充NAN或者可選的填充值 set_index/reset_index,,互為逆操作,前者是將已有的一列信息設(shè)置為標(biāo)簽列,而后者是將原標(biāo)簽列歸為數(shù)據(jù),,并重置為默認(rèn)數(shù)字標(biāo)簽 set_axis,,設(shè)置標(biāo)簽列,一次只能設(shè)置一列信息,,與rename功能相近,,但接收參數(shù)為一個(gè)序列更改全部標(biāo)簽列信息(rename中是接收字典,允許只更改部分信息) - rename_axis,,重命名標(biāo)簽名,,rename中也可實(shí)現(xiàn)相同功能
在pandas早些版本中,除一維數(shù)據(jù)結(jié)構(gòu)series和二維數(shù)據(jù)結(jié)構(gòu)dataframe外,,還支持三維數(shù)據(jù)結(jié)構(gòu)panel,。這三者是構(gòu)成遞進(jìn)包容關(guān)系,panel即是dataframe的容器,,用于存儲多個(gè)dataframe。2019年7月,,隨著pandas 0.25版本的推出,,pandas團(tuán)隊(duì)宣布正式棄用panel數(shù)據(jù)結(jié)構(gòu),而相應(yīng)功能建議由多層索引實(shí)現(xiàn),。 也正因?yàn)閜andas這3種獨(dú)特的數(shù)據(jù)結(jié)構(gòu),,個(gè)人一度認(rèn)為pandas包名解釋為:pandas = panel + dataframe + series,根據(jù)維數(shù)取相應(yīng)的首字母個(gè)數(shù),,從而構(gòu)成pandas,,這是個(gè)人非常喜歡的一種關(guān)于pandas縮寫的解釋。
pandas支持大部分的主流文件格式進(jìn)行數(shù)據(jù)讀寫,,常用格式及接口為:
文本文件,主要包括csv和txt兩種等,,相應(yīng)接口為read_csv()和to_csv(),,分別用于讀寫數(shù)據(jù) Excel文件,包括xls和xlsx兩種格式均得到支持,,底層是調(diào)用了xlwt和xlrd進(jìn)行excel文件操作,,相應(yīng)接口為read_excel()和to_excel() SQL文件,支持大部分主流關(guān)系型數(shù)據(jù)庫,,例如MySQL,,需要相應(yīng)的數(shù)據(jù)庫模塊支持,相應(yīng)接口為read_sql()和to_sql()
此外,pandas還支持html,、json等文件格式的讀寫操作,。 series和dataframe兼具numpy數(shù)組和字典的結(jié)構(gòu)特性,,所以數(shù)據(jù)訪問都是從這兩方面入手,。同時(shí),也支持bool索引進(jìn)行數(shù)據(jù)訪問和篩選,。 切片形式返回行查詢,,且為范圍查詢
切片類型與索引列類型不一致時(shí),,引發(fā)報(bào)錯(cuò)
- query,,按列對dataframe執(zhí)行條件查詢,一般可用常規(guī)的條件查詢替代
- get,,由于series和dataframe均可以看做是類字典結(jié)構(gòu),,所以也可使用字典中的get()方法,主要適用于不確定數(shù)據(jù)結(jié)構(gòu)中是否包含該標(biāo)簽時(shí),,與字典的get方法完全一致
- lookup,,loc的一種特殊形式,分別傳入一組行標(biāo)簽和列標(biāo)簽,,lookup解析成一組行列坐標(biāo),返回相應(yīng)結(jié)果:
pandas中支持大量的數(shù)據(jù)訪問接口,,但萬變不離其宗:只要聯(lián)想兩種數(shù)據(jù)結(jié)構(gòu)兼具numpy數(shù)組和字典的雙重特性,,就不難理解這些數(shù)據(jù)訪問的邏輯原理。當(dāng)然,,重點(diǎn)還是掌握[],、loc和iloc三種方法。
loc和iloc應(yīng)該理解為是series和dataframe的屬性而非函數(shù),,應(yīng)用loc和iloc進(jìn)行數(shù)據(jù)訪問就是根據(jù)屬性值訪問的過程 另外,,在pandas早些版本中,還存在loc和iloc的兼容結(jié)構(gòu),,即ix,,可混合使用標(biāo)簽和數(shù)字索引,但往往容易混亂,,所以現(xiàn)已棄用
pandas最為強(qiáng)大的功能當(dāng)然是數(shù)據(jù)處理和分析,,可獨(dú)立完成數(shù)據(jù)分析前的絕大部分?jǐn)?shù)據(jù)預(yù)處理需求。簡單歸納來看,,主要可分為以下幾個(gè)方面: 數(shù)據(jù)處理中的清洗工作主要包括對空值、重復(fù)值和異常值的處理:- 檢測重復(fù)值,duplicated,,檢測各行是否重復(fù),,返回一個(gè)行索引的bool結(jié)果,可通過keep參數(shù)設(shè)置保留第一行/最后一行/無保留,,例如keep=first意味著在存在重復(fù)的多行時(shí),,首行被認(rèn)為是合法的而可以保留
刪除重復(fù)值,drop_duplicates,,按行檢測并刪除重復(fù)的記錄,,也可通過keep參數(shù)設(shè)置保留項(xiàng)。由于該方法默認(rèn)是按行進(jìn)行檢測,,如果存在某個(gè)需要需要按列刪除,,則可以先轉(zhuǎn)置再執(zhí)行該方法
- 異常值,判斷異常值的標(biāo)準(zhǔn)依賴具體分析數(shù)據(jù),,所以這里僅給出兩種處理異常值的可選方法
- 刪除,,drop,,接受參數(shù)在特定軸線執(zhí)行刪除一條或多條記錄,可通過axis參數(shù)設(shè)置是按行刪除還是按列刪除
- 替換,,replace,,非常強(qiáng)大的功能,對series或dataframe中每個(gè)元素執(zhí)行按條件替換操作,,還可開啟正則表達(dá)式功能
由于pandas是在numpy的基礎(chǔ)上實(shí)現(xiàn)的,所以numpy的常用數(shù)值計(jì)算操作在pandas中也適用:
- 通函數(shù)ufunc,,即可以像操作標(biāo)量一樣對series或dataframe中的所有元素執(zhí)行同一操作,,這與numpy的特性是一致的,例如前文提到的replace函數(shù),,本質(zhì)上可算作是通函數(shù),。如下實(shí)現(xiàn)對數(shù)據(jù)表中逐元素求平方
- 廣播機(jī)制,即當(dāng)維度或形狀不匹配時(shí),,會按一定條件廣播后計(jì)算,。由于pandas是帶標(biāo)簽的數(shù)組,所以在廣播過程中會自動按標(biāo)簽匹配進(jìn)行廣播,,而非類似numpy那種純粹按順序進(jìn)行廣播,。例如,如下示例中執(zhí)行一個(gè)dataframe和series相乘,,雖然二者維度不等,、大小不等、標(biāo)簽順序也不一致,,但仍能按標(biāo)簽匹配得到預(yù)期結(jié)果
- 字符串向量化,即對于數(shù)據(jù)類型為字符串格式的一列執(zhí)行向量化的字符串操作,,本質(zhì)上是調(diào)用series.str屬性的系列接口,,完成相應(yīng)的字符串操作。尤為強(qiáng)大的是,,除了常用的字符串操作方法,,str屬性接口中還集成了正則表達(dá)式的大部分功能,這使得pandas在處理字符串列時(shí),,兼具高效和強(qiáng)力,。例如如下代碼可用于統(tǒng)計(jì)每個(gè)句子中單詞的個(gè)數(shù)
需注意的是,這里的字符串接口與python中普通字符串的接口形式上很是相近,,但二者是不一樣的,。 - 時(shí)間類型向量化操作,,如字符串一樣,在pandas中另一個(gè)得到'優(yōu)待'的數(shù)據(jù)類型是時(shí)間類型,,正如字符串列可用str屬性調(diào)用字符串接口一樣,,時(shí)間類型列可用dt屬性調(diào)用相應(yīng)接口,這在處理時(shí)間類型時(shí)會十分有效,。
前文提到,在處理特定值時(shí)可用replace對每個(gè)元素執(zhí)行相同的操作,,然而replace一般僅能用于簡單的替換操作,,所以pandas還提供了更為強(qiáng)大的數(shù)據(jù)轉(zhuǎn)換方法 - map,適用于series對象,,功能與python中的普通map函數(shù)類似,,即對給定序列中的每個(gè)值執(zhí)行相同的映射操作,不同的是series中的map接口的映射方式既可以是一個(gè)函數(shù),,也可以是一個(gè)字典
- apply,,既適用于series對象也適用于dataframe對象,但對二者處理的粒度是不一樣的:apply應(yīng)用于series時(shí)是逐元素執(zhí)行函數(shù)操作,;apply應(yīng)用于dataframe時(shí)是逐行或者逐列執(zhí)行函數(shù)操作(通過axis參數(shù)設(shè)置對行還是對列,,默認(rèn)是行),僅接收函數(shù)作為參數(shù)
- applymap,,僅適用于dataframe對象,,且是對dataframe中的每個(gè)元素執(zhí)行函數(shù)操作,從這個(gè)角度講,,與replace類似,,applymap可看作是dataframe對象的通函數(shù)。
pandas中又一個(gè)重量級數(shù)據(jù)處理功能是對多個(gè)dataframe進(jìn)行合并與拼接,,對應(yīng)SQL中兩個(gè)非常重要的操作:union和join。pandas完成這兩個(gè)功能主要依賴以下函數(shù): concat,,與numpy中的concatenate類似,,但功能更為強(qiáng)大,可通過一個(gè)axis參數(shù)設(shè)置是橫向或者拼接,,要求非拼接軸向標(biāo)簽唯一(例如沿著行進(jìn)行拼接時(shí),,要求每個(gè)df內(nèi)部列名是唯一的,,但兩個(gè)df間可以重復(fù),畢竟有相同列才有拼接的實(shí)際意義) merge,,完全類似于SQL中的join語法,,僅支持橫向拼接,通過設(shè)置連接字段,,實(shí)現(xiàn)對同一記錄的不同列信息連接,,支持inner、left,、right和outer4種連接方式,,但只能實(shí)現(xiàn)SQL中的等值連接 join,語法和功能與merge一致,,不同的是merge既可以用pandas接口調(diào)用,,也可以用dataframe對象接口調(diào)用,而join則只適用于dataframe對象接口 append,,concat執(zhí)行axis=0時(shí)的一個(gè)簡化接口,,類似列表的append函數(shù)一樣 實(shí)際上,concat通過設(shè)置axis=1也可實(shí)現(xiàn)與merge類似的效果,,二者的區(qū)別在于:merge允許連接字段重復(fù),,類似一對多或者多對一連接,此時(shí)將產(chǎn)生笛卡爾積結(jié)果,;而concat則不允許重復(fù),,僅能一對一拼接。建表語句 通過設(shè)置參數(shù),,concat和merge實(shí)現(xiàn)相同效果
pandas中的另一大類功能是數(shù)據(jù)分析,通過豐富的接口,,可實(shí)現(xiàn)大量的統(tǒng)計(jì)需求,,包括Excel和SQL中的大部分分析過程,在pandas中均可以實(shí)現(xiàn),。
pandas內(nèi)置了豐富的統(tǒng)計(jì)接口,,這是與numpy是一致的,,同時(shí)又包括一些常用統(tǒng)計(jì)信息的集成接口,。 info,展示行標(biāo)簽,、列標(biāo)簽,、以及各列基本信息,包括元素個(gè)數(shù)和非空個(gè)數(shù)及數(shù)據(jù)類型等 head/tail,,從頭/尾抽樣指定條數(shù)記錄 - describe,,展示數(shù)據(jù)的基本統(tǒng)計(jì)指標(biāo),包括計(jì)數(shù),、均值,、方差、4分位數(shù)等,,還可接收一個(gè)百分位參數(shù)列表展示更多信息
- count,、value_counts,前者既適用于series也適用于dataframe,,用于按列統(tǒng)計(jì)個(gè)數(shù),,實(shí)現(xiàn)忽略空值后的計(jì)數(shù);而value_counts則僅適用于series,,執(zhí)行分組統(tǒng)計(jì),,并默認(rèn)按頻數(shù)高低執(zhí)行降序排列,在統(tǒng)計(jì)分析中很有用
- unique,、nunique,,也是僅適用于series對象,統(tǒng)計(jì)唯一值信息,,前者返回唯一值結(jié)果列表,,后者返回唯一值個(gè)數(shù)(number of unique)
- sort_index、sort_values,,既適用于series也適用于dataframe,,sort_index是對標(biāo)簽列執(zhí)行排序,如果是dataframe可通過axis參數(shù)設(shè)置是對行標(biāo)簽還是列標(biāo)簽執(zhí)行排序,;sort_values是按值排序,,如果是dataframe對象,也可通過axis參數(shù)設(shè)置排序方向是行還是列,,同時(shí)根據(jù)by參數(shù)傳入指定的行或者列,,可傳入多行或多列并分別設(shè)置升序降序參數(shù),非常靈活,。另外,,在標(biāo)簽列已經(jīng)命名的情況下,sort_values可通過by標(biāo)簽名實(shí)現(xiàn)與sort_index相同的效果。
pandas的另一個(gè)強(qiáng)大的數(shù)據(jù)分析功能是分組聚合以及數(shù)據(jù)透視表,,前者堪比SQL中的groupby,后者媲美Excel中的數(shù)據(jù)透視表,。- groupby,,類比SQL中的group by功能,即按某一列或多列執(zhí)行分組,。一般而言,,分組的目的是為了后續(xù)的聚合統(tǒng)計(jì),所有g(shù)roupby函數(shù)一般不單獨(dú)使用,,而需要級聯(lián)其他聚合函數(shù)共同完成特定需求,,例如分組求和、分組求均值等,。
pandas官網(wǎng)關(guān)于groupby過程的解釋 級聯(lián)其他聚合函數(shù)的方式一般有兩種:單一的聚合需求用groupby+聚合函數(shù)即可,,復(fù)雜的大量聚合則可借用agg函數(shù),agg函數(shù)接受多種參數(shù)形式作為聚合函數(shù),,功能更為強(qiáng)大,。兩種分組聚合形式 - pivot,pivot英文有'支點(diǎn)'或者'旋轉(zhuǎn)'的意思,,排序算法中經(jīng)典的快速排序就是不斷根據(jù)pivot不斷將數(shù)據(jù)二分,,從而加速排序過程。用在這里,,實(shí)際上就是執(zhí)行行列重整,。例如,以某列取值為重整后行標(biāo)簽,,以另一列取值作為重整后的列標(biāo)簽,,以其他列取值作為填充value,即實(shí)現(xiàn)了數(shù)據(jù)表的行列重整,。以SQL中經(jīng)典的學(xué)生成績表為例,,給定原始學(xué)生—課程—成績表,需重整為學(xué)生vs課程的成績表,,則可應(yīng)用pivot實(shí)現(xiàn):
另外,,還有一對函數(shù)也常用于數(shù)據(jù)重整,即stack和unstack,,其中unstack執(zhí)行效果與pivot非常類似,,而stack則是unstack的逆過程。 - pivot_table,有了pivot就不難理解pivot_table,,實(shí)際上它是在前者的基礎(chǔ)上增加了聚合的過程,類似于Excel中的數(shù)據(jù)透視表功能,。仍然考慮前述學(xué)生成績表的例子,,但是再增加一列班級信息,需求是統(tǒng)計(jì)各班級每門課程的平均分,。由于此時(shí)各班的每門課成績信息不唯一,,所以直接用pivot進(jìn)行重整會報(bào)錯(cuò),此時(shí)即需要對各班各門課程成績進(jìn)行聚合后重整,,比如取平均分,。
pandas集成了matplotlib中的常用可視化圖形接口,,可通過series和dataframe兩種數(shù)據(jù)結(jié)構(gòu)面向?qū)ο蟮慕涌诜绞胶唵握{(diào)用,。關(guān)于面向?qū)ο蠼涌诤蚿lt接口繪圖方式的區(qū)別,可參考python數(shù)據(jù)科學(xué)系列:matplotlib入門詳細(xì)教程,。
兩種數(shù)據(jù)結(jié)構(gòu)作圖,,區(qū)別僅在于series是繪制單個(gè)圖形,而dataframe則是繪制一組圖形,,且在dataframe繪圖結(jié)果中以列名為標(biāo)簽自動添加legend,。另外,均支持兩種形式的繪圖接口:
不過,pandas繪圖中僅集成了常用的圖表接口,,更多復(fù)雜的繪圖需求往往還需依賴matplotlib或者其他可視化庫,。
|