作者:luanhz
來源:小數志
本文主要是對pandas進行入門詳細介紹,通過本文你將系統性了解pandas為何會有數據分析界"瑞士軍刀"的盛譽。
行文二級目錄
pandas,python+data+analysis的組合縮寫,是python中基於numpy和matplotlib的第三方數據分析庫,與後兩者共同構成了python數據分析的基礎工具包,享有數分三劍客之名。
series和dataframe分別是一維和二維數組,因為是數組,所以numpy中關於數組的用法基本可以直接應用到這兩個數據結構,包括數據創建、切片訪問、通函數、廣播機制等
series是帶標籤的一維數組,所以還可以看做是類字典結構:標籤是key,取值是value;而dataframe則可以看做是嵌套字典結構,其中列名是key,每一列的series是value。所以從這個角度講,pandas數據創建的一種靈活方式就是通過字典或者嵌套字典,同時也自然衍生出了適用於series和dataframe的類似字典訪問的接口,即通過loc索引訪問。
注意,這裡強調series和dataframe是一個類字典結構而非真正意義上的字典,原因在於series中允許標籤名重複、dataframe中則允許列名和標籤名均有重複,而這是一個真正字典所不允許的。
ndim/shape/dtypes/size/T,分別表示了數據的維數、形狀、數據類型和元素個數以及轉置結果。其中,由於pandas允許數據類型是異構的,各列之間可能含有多種不同的數據類型,所以dtype取其複數形式dtypes。與此同時,series因為只有一列,所以數據類型自然也就只有一種,pandas為了兼容二者,series的數據類型屬性既可以用dtype也可以用dtypes獲取;而dataframe則只能用dtypes。
index/columns/values,分別對應了行標籤、列標籤和數據,其中數據就是一個格式向上兼容所有列數據類型的array。為了沿襲字典中的訪問習慣,還可以用keys()訪問標籤信息,在series返回index標籤,在dataframe中則返回columns列名;可以用items()訪問鍵值對,但一般用處不大。
關於series和dataframe數據結構本身,有大量的方法可用於重構結構信息:
rename,可以對標籤名重命名,也可以重置index和columns的部分標籤列信息,接收標量(用於對標籤名重命名)或字典(用於重命名行標籤和列標籤)
reindex,接收一個新的序列與已有標籤列匹配,當原標籤列中不存在相應信息時,填充NAN或者可選的填充值
set_index/reset_index,互為逆操作,前者是將已有的一列信息設置為標籤列,而後者是將原標籤列歸為數據,並重置為默認數字標籤
set_axis,設置標籤列,一次只能設置一列信息,與rename功能相近,但接收參數為一個序列更改全部標籤列信息(rename中是接收字典,允許只更改部分信息)
rename_axis,重命名標籤名,rename中也可實現相同功能在pandas早些版本中,除一維數據結構series和二維數據結構dataframe外,還支持三維數據結構panel。這三者是構成遞進包容關係,panel即是dataframe的容器,用於存儲多個dataframe。2019年7月,隨著pandas 0.25版本的推出,pandas團隊宣布正式棄用panel數據結構,而相應功能建議由多層索引實現。
也正因為pandas這3種獨特的數據結構,個人一度認為pandas包名解釋為:pandas = panel + dataframe + series,根據維數取相應的首字母個數,從而構成pandas,這是個人非常喜歡的一種關於pandas縮寫的解釋。
文本文件,主要包括csv和txt兩種等,相應接口為read_csv()和to_csv(),分別用於讀寫數據
Excel文件,包括xls和xlsx兩種格式均得到支持,底層是調用了xlwt和xlrd進行excel文件操作,相應接口為read_excel()和to_excel()
SQL文件,支持大部分主流關係型資料庫,例如MySQL,需要相應的資料庫模塊支持,相應接口為read_sql()和to_sql()
此外,pandas還支持html、json等文件格式的讀寫操作。
series和dataframe兼具numpy數組和字典的結構特性,所以數據訪問都是從這兩方面入手。同時,也支持bool索引進行數據訪問和篩選。
切片形式返回行查詢,且為範圍查詢
切片類型與索引列類型不一致時,引發報錯
pandas中支持大量的數據訪問接口,但萬變不離其宗:只要聯想兩種數據結構兼具numpy數組和字典的雙重特性,就不難理解這些數據訪問的邏輯原理。當然,重點還是掌握[]、loc和iloc三種方法。
loc和iloc應該理解為是series和dataframe的屬性而非函數,應用loc和iloc進行數據訪問就是根據屬性值訪問的過程
另外,在pandas早些版本中,還存在loc和iloc的兼容結構,即ix,可混合使用標籤和數字索引,但往往容易混亂,所以現已棄用
pandas最為強大的功能當然是數據處理和分析,可獨立完成數據分析前的絕大部分數據預處理需求。簡單歸納來看,主要可分為以下幾個方面:
數據處理中的清洗工作主要包括對空值、重複值和異常值的處理:異常值,判斷異常值的標準依賴具體分析數據,所以這裡僅給出兩種處理異常值的可選方法刪除,drop,接受參數在特定軸線執行刪除一條或多條記錄,可通過axis參數設置是按行刪除還是按列刪除替換,replace,非常強大的功能,對series或dataframe中每個元素執行按條件替換操作,還可開啟正則表達式功能由於pandas是在numpy的基礎上實現的,所以numpy的常用數值計算操作在pandas中也適用:
前文提到,在處理特定值時可用replace對每個元素執行相同的操作,然而replace一般僅能用於簡單的替換操作,所以pandas還提供了更為強大的數據轉換方法
map,適用於series對象,功能與python中的普通map函數類似,即對給定序列中的每個值執行相同的映射操作,不同的是series中的map接口的映射方式既可以是一個函數,也可以是一個字典apply,既適用於series對象也適用於dataframe對象,但對二者處理的粒度是不一樣的:apply應用於series時是逐元素執行函數操作;apply應用於dataframe時是逐行或者逐列執行函數操作(通過axis參數設置對行還是對列,默認是行),僅接收函數作為參數applymap,僅適用於dataframe對象,且是對dataframe中的每個元素執行函數操作,從這個角度講,與replace類似,applymap可看作是dataframe對象的通函數。pandas中又一個重量級數據處理功能是對多個dataframe進行合併與拼接,對應SQL中兩個非常重要的操作:union和join。pandas完成這兩個功能主要依賴以下函數:
concat,與numpy中的concatenate類似,但功能更為強大,可通過一個axis參數設置是橫向或者拼接,要求非拼接軸向標籤唯一(例如沿著行進行拼接時,要求每個df內部列名是唯一的,但兩個df間可以重複,畢竟有相同列才有拼接的實際意義)
merge,完全類似於SQL中的join語法,僅支持橫向拼接,通過設置連接欄位,實現對同一記錄的不同列信息連接,支持inner、left、right和outer4種連接方式,但只能實現SQL中的等值連接
join,語法和功能與merge一致,不同的是merge既可以用pandas接口調用,也可以用dataframe對象接口調用,而join則只適用於dataframe對象接口
append,concat執行axis=0時的一個簡化接口,類似列表的append函數一樣
實際上,concat通過設置axis=1也可實現與merge類似的效果,二者的區別在於:merge允許連接欄位重複,類似一對多或者多對一連接,此時將產生笛卡爾積結果;而concat則不允許重複,僅能一對一拼接。建表語句
通過設置參數,concat和merge實現相同效果
pandas中的另一大類功能是數據分析,通過豐富的接口,可實現大量的統計需求,包括Excel和SQL中的大部分分析過程,在pandas中均可以實現。
pandas內置了豐富的統計接口,這是與numpy是一致的,同時又包括一些常用統計信息的集成接口。
pandas官網關於groupby過程的解釋
級聯其他聚合函數的方式一般有兩種:單一的聚合需求用groupby+聚合函數即可,複雜的大量聚合則可借用agg函數,agg函數接受多種參數形式作為聚合函數,功能更為強大。兩種分組聚合形式
pivot,pivot英文有"支點"或者"旋轉"的意思,排序算法中經典的快速排序就是不斷根據pivot不斷將數據二分,從而加速排序過程。用在這裡,實際上就是執行行列重整。例如,以某列取值為重整後行標籤,以另一列取值作為重整後的列標籤,以其他列取值作為填充value,即實現了數據表的行列重整。以SQL中經典的學生成績表為例,給定原始學生—課程—成績表,需重整為學生vs課程的成績表,則可應用pivot實現:另外,還有一對函數也常用於數據重整,即stack和unstack,其中unstack執行效果與pivot非常類似,而stack則是unstack的逆過程。pivot_table,有了pivot就不難理解pivot_table,實際上它是在前者的基礎上增加了聚合的過程,類似於Excel中的數據透視表功能。仍然考慮前述學生成績表的例子,但是再增加一列班級信息,需求是統計各班級每門課程的平均分。由於此時各班的每門課成績信息不唯一,所以直接用pivot進行重整會報錯,此時即需要對各班各門課程成績進行聚合後重整,比如取平均分。pandas集成了matplotlib中的常用可視化圖形接口,可通過series和dataframe兩種數據結構面向對象的接口方式簡單調用。關於面向對象接口和plt接口繪圖方式的區別,可參考python數據科學系列:matplotlib入門詳細教程。
不過,pandas繪圖中僅集成了常用的圖表接口,更多複雜的繪圖需求往往還需依賴matplotlib或者其他可視化庫。