華振宇
摘要:Pandas和NumPy作為Python數(shù)據(jù)分析框架下的兩個第三方庫,已成為數(shù)據(jù)科學領(lǐng)域相關(guān)工作的常見工具和技術(shù)。文章在簡要介紹Pandas和NumPy特點的基礎(chǔ)之上,從開源社區(qū)支持、基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)、內(nèi)存占用、數(shù)據(jù)兼容性、性能表現(xiàn)、數(shù)據(jù)對象、數(shù)據(jù)類型、訪問方法、索引功能、可操作性、文件存儲、使用場景、機器學習和人工智能中的應(yīng)用等方面,細致比較了二者之間的異同,以期幫助研究者更加合理地選擇和使用這兩個第三方庫。
關(guān)鍵詞:Pandas;NumPy;Python
中圖分類號:TP311? ? ? 文獻標識碼:A
文章編號:1009-3044(2023)01-0071-03
1 引言
我國《“十四五”數(shù)字經(jīng)濟規(guī)劃》中明確提出要“充分發(fā)揮數(shù)據(jù)要素作用”,數(shù)據(jù)科學相關(guān)的研究工作在我國當前的發(fā)展形勢可謂如火如荼。Python作為近年持續(xù)流行的主流編程語言之一,由于其語法簡潔、功能強大,且具有能夠提供完整數(shù)據(jù)分析框架的成熟開發(fā)生態(tài),早已成為人工智能、大數(shù)據(jù)、機器學習等領(lǐng)域研究工作的常見工具和選擇[1-2]。本文在扼要介紹Python生態(tài)中的兩個科學計算庫:NumPy和Pandas的基礎(chǔ)之上,簡明概括二者之間的異同,以期能夠幫助讀者迅速理解和掌握這兩個工具的使用,并以此為基礎(chǔ)開展自己的數(shù)據(jù)研究工作。
2 NumPy及其簡介
NumPy(Numerical Python)是一個開源的Python科學計算庫,是Python生態(tài)中最重要的底層支持庫之一,支持快速的數(shù)組和矩陣運算[3]。NumPy 1.0發(fā)布于2006年,目前的最新版本是1.23。NumPy具有如下特點:
1) 使用數(shù)組作為其內(nèi)部數(shù)據(jù)結(jié)構(gòu),而非Python列表中所使用的對象指針,因此其訪問性能遠遠超出原生的Python列表結(jié)構(gòu);
2) 代碼采用C/C++實現(xiàn),具有極為優(yōu)異的運行效率;
3) 通常用于組織同構(gòu)(質(zhì))的數(shù)據(jù)對象;
4) 可以表達一維或多維數(shù)組;
5) 支持線性代數(shù)、數(shù)理統(tǒng)計、多項式、傅里葉變換等多種數(shù)學計算;
6) 支持數(shù)組的組合、分割、形狀改變、排序等操作;
7) 當參與運算的兩個數(shù)組形狀不一致時,將按照廣播規(guī)則進行運算,規(guī)則如下:
①參加運算的數(shù)組都向維數(shù)最大的數(shù)組看齊,維數(shù)較小的數(shù)組在前面加1補齊;
②結(jié)果數(shù)組的形狀取各運算數(shù)組各軸的最大值;
③若運算數(shù)組某軸長度為1,則該軸可擴充為結(jié)果數(shù)組的對應(yīng)軸的長度,否則不能擴充;
④檢查擴充后所有運算數(shù)組的各軸長度,全部相同則符合規(guī)則可以計算,否則違反規(guī)則無法計算。
8) 已被其他第三方庫:如Pandas、Seaborn、TensorFlow等包含使用[4]。
關(guān)鍵代碼示例:
假定已通過import numpy as np進行導入。
1) 創(chuàng)建一個包含4行3列的二維數(shù)組
arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
輸出數(shù)組如圖1所示:
2) 使用基本索引獲取其中某個數(shù)據(jù)
NumPy中的索引操作和Python中的原生列表類型相似。索引總是從0開始編號,并且書寫于一對中括號內(nèi)部。假設(shè)想從如上矩陣中訪問第三行第二列的元素(7) ,應(yīng)使用如下表達式:
arr[2][1]
3) 使用切片獲取數(shù)據(jù)子集
如果需要一次性地獲取多個數(shù)據(jù),則應(yīng)使用切片操作。在NumPy中,需要分別指定行的范圍和列的范圍。依然以上文矩陣為例,如果需要訪問第一行和第二行,第二列和第三列共同構(gòu)成的數(shù)據(jù)子集,可使用如下表達式:
arr[0:2, 1:3]
當使用a:b這樣的形式表達一個特定范圍時,具體的取值范圍應(yīng)該是a, a+1, ... , b-1(數(shù)值b應(yīng)該被排除在外)。最終的輸出結(jié)果如圖2所示:
4) 矩陣的轉(zhuǎn)置操作
正如前文提及,NumPy內(nèi)置大量的矩陣運算函數(shù)。方法transpose()直接返回給定矩陣的轉(zhuǎn)置矩陣。輸出結(jié)果如圖3所示:
3 Pandas及其簡介
Pandas是目前Python生態(tài)中最常用的數(shù)據(jù)分析工具庫之一。該庫以NumPy為基礎(chǔ),增加了標簽支持,整合了對數(shù)據(jù)集的讀取、清洗、轉(zhuǎn)換、分析、統(tǒng)計、繪圖等一系列工作流程,能夠高效地處理和分析各類數(shù)據(jù)[5]。Pandas提供了兩種最基本的數(shù)據(jù)結(jié)構(gòu):序列(Series) 和數(shù)據(jù)框(DataFrame) ,分別用于帶標簽的一維數(shù)組和二維數(shù)組的表示。Pandas具有如下特點:
1) 能夠處理殘缺數(shù)據(jù);
2) 支持可視化,能夠生成常見的圖表,如餅圖、直方圖、關(guān)聯(lián)圖等;
3) 強大的分組和排序功能;
4) 支持對各種主流文件格式的導入導出,如csv,hdf5,xlsx;
5) 支持數(shù)據(jù)的合并、清洗和索引重建;
6) 內(nèi)置loc和iloc取數(shù)器獲取數(shù)據(jù)子集,其中l(wèi)oc允許用戶通過標簽獲取子集,而iloc則借助整數(shù)索引下標;
7) 通過groupby()方法支持分組統(tǒng)計;
8) 通過apply()方法,可由匿名lambda函數(shù)對各行或各列進行數(shù)據(jù)變換;
9) 提供內(nèi)置函數(shù)可對空值、缺失數(shù)據(jù)項進行清洗。
關(guān)鍵代碼示例:
假定已通過import pandas as np及 from pandas import Series, DataFrame進行導入。
①創(chuàng)建數(shù)據(jù)框?qū)ο?/p>
以前述創(chuàng)建的二維數(shù)組arr為基礎(chǔ),構(gòu)造一個攜帶行標簽和列標簽的四行三列的數(shù)據(jù)框?qū)ο蟆4a如下:
df = DataFrame(arr, index=list('abcd'), columns=list('xyz'))
輸出數(shù)據(jù)框如圖4所示:
②通過標簽訪問數(shù)據(jù)框中的某個數(shù)據(jù)
依然以訪問第三行第二列的數(shù)值7為例,其表達式應(yīng)為:
df.loc['c']['y'] 或 df.loc['c', 'y']
③使用基于標簽的切片獲取子數(shù)據(jù)框
與NumPy相似,Pandas中同樣支持切片——而且提供基于標簽的切片。當使用整數(shù)索引切片時,冒號后的數(shù)字不被包括在內(nèi);如果使用標簽切片,冒號前后的標簽都應(yīng)包括在內(nèi)。在以上數(shù)據(jù)框中,如欲獲取包含第一、二行,第二、三列構(gòu)成的子數(shù)據(jù)框,則可使用如下表達式:
df.loc['a':'b', 'y':'z']
當然,Pandas提供iloc作為基于整數(shù)索引的切片訪問方式,代碼為:
df.iloc[0:2, 1:3] (與NumPy中的切片相似)
獲取的子數(shù)據(jù)框輸出如圖5所示:
④排序
Pandas中排序可以作用于索引或數(shù)據(jù)值。對行或列索引排序時使用sort_index()方法,按數(shù)據(jù)值排序時使用sort_values()方法。排序后返回一個有序的新對象,而不直接改變原數(shù)據(jù)框的排列順序。使用sort_index()方法時,有兩個常見的可選參數(shù):ascending和axis。ascending默認取值為True表示按升序排序,若設(shè)為False則按降序排列。axis默認取值為0表示對行索引進行排序,若設(shè)為1則對列索引進行排序。假如對數(shù)據(jù)框df的列索引進行降序排序,則按如下方式調(diào)用函數(shù):
df.sort_index(ascending=False, axis=1)
運行以上代碼輸出如圖6所示:
sort_values()同樣支持ascending和axis參數(shù)。axis默認取值為0表示對列進行排序,若設(shè)為1則對行進行排序。此外,由于數(shù)據(jù)框存在多行或者多列,必須通過by參數(shù)指定參與排序的行或列。假如對數(shù)據(jù)框df按x列數(shù)據(jù)降序排列,則應(yīng)按如下方式進行函數(shù)調(diào)用:
df.sort_values(ascending=False, by='x')
運行以上代碼輸出如圖7所示:
4 Pandas和NumPy的比較
Pandas基于NumPy實現(xiàn),同時廣泛應(yīng)用于數(shù)據(jù)科學相關(guān)領(lǐng)域工作,二者之間可謂既有區(qū)別又有聯(lián)系。以下將從開源社區(qū)支持、基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)、內(nèi)存占用、數(shù)據(jù)兼容性、性能表現(xiàn)等13個方面,逐一對Pandas和NumPy進行細致的比較:
1) 開源社區(qū)支持
Pandas和NumPy均為開源代碼庫,因此其開源社區(qū)的研發(fā)水平、活躍程度對于代碼庫的后續(xù)發(fā)展和維護,都起著至關(guān)重要的作用。表1總結(jié)了截止筆者撰寫本文時這兩個代碼庫在GitHub上的相關(guān)統(tǒng)計數(shù)據(jù):
由此不難發(fā)現(xiàn):目前這兩個代碼庫在開源社區(qū)都享有較高的關(guān)注度和活躍度,預(yù)期在將來依然可以得到良好的發(fā)展與維護。
2) 基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)
Pandas提供的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)是序列(Series) 和數(shù)據(jù)框(DataFrame) 。序列是帶有標簽的一維數(shù)組;而數(shù)據(jù)框則可視為由多個具有相同標簽的序列構(gòu)成的二維數(shù)組。數(shù)據(jù)框可同時附帶行標簽和列標簽。NumPy則以N維數(shù)組(ndarray) 作為基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)。
3) 內(nèi)存占用
NumPy的內(nèi)存占用要小于Pandas。原因在于:Pandas依然使用對象指針表示序列和數(shù)據(jù)框中的數(shù)據(jù)。此外,Pandas還需要額外存儲數(shù)據(jù)的標簽(索引)。
4) 數(shù)據(jù)兼容性
Pandas基于NumPy實現(xiàn),適用于任何扁平(表格)結(jié)構(gòu)數(shù)據(jù)的處理。而NumPy更常見于純粹的數(shù)值或矩陣運算。
5) 性能表現(xiàn)
二者均提供了基于IRIS數(shù)據(jù)集的性能測試報告。測試結(jié)果表明,當數(shù)據(jù)記錄條數(shù)在5萬以下時,NumPy具有更好的運算性能。如果超出50萬條記錄,Pandas的表現(xiàn)更勝一籌。如果數(shù)據(jù)規(guī)模介于5萬和50萬條記錄之間,關(guān)于二者之間孰優(yōu)孰劣尚無明顯定論。由此可見:當數(shù)據(jù)集的規(guī)模較小時,NumPy能夠提供更好的性能表現(xiàn);反之,理應(yīng)優(yōu)先考慮Pandas。
6) 數(shù)據(jù)對象
Pandas不僅提供序列和數(shù)據(jù)框作為表達一維和二維數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ)數(shù)據(jù)類型,甚至還設(shè)計了表達三維數(shù)據(jù)結(jié)構(gòu)的Panel數(shù)據(jù)類型;然后在Pandas的相關(guān)實踐中鮮少遇見對Panel類型的使用。而NumPy則可支持N維數(shù)組。
7) 數(shù)據(jù)類型
NumPy中的數(shù)組和Pandas中的序列/數(shù)據(jù)框類型均可作為字符串、整數(shù)、浮點數(shù)、列表等的容器類型。不同之處在于:Pandas中,數(shù)據(jù)框的數(shù)據(jù)元素類型可以是異質(zhì)的——換言之,每一列均可定義自己的特有類型。而NumPy中的數(shù)組類型,其全部數(shù)據(jù)元素擁有相同的數(shù)據(jù)類型——換言之,所有數(shù)據(jù)必須同質(zhì)。
8) 訪問方法
無論是在NumPy還是Pandas中,都能通過整數(shù)索引訪問某個特定的數(shù)據(jù)、切片或者數(shù)據(jù)子集。由于Pandas集成了標簽特性,還可以通過指定行標簽或者列標簽的方式來訪問數(shù)據(jù)——由于標簽本身能夠體現(xiàn)數(shù)據(jù)語義,這一方式對于編程者來說無疑更為友好。
9) 索引功能
NumPy本質(zhì)上使用數(shù)組實現(xiàn),因此自帶數(shù)組的快速索引這一天然優(yōu)勢;而Pandas基于NumPy實現(xiàn),且必須在此基礎(chǔ)上新增支持行標簽和列標簽的索引模塊,其索引速度必然慢于NumPy。
10) 可操作性
Pandas支持分組統(tǒng)計(通過groupby()方法)、多級排序這樣的復雜操作,其操作能力可類比標準查詢語言SQL;而NumPy提供的操作函數(shù)和方法,全部限于數(shù)學和矩陣運算。
11) 文件存儲
無論是Pandas還是NumPy,都支持對于外部文件的導入導出——例如對于主流的數(shù)據(jù)文件格式csv,二者均能提供完美支持。但相較于NumPy,Pandas支持的文件類型更為豐富,還包括:xlsx,HDF5甚至某些數(shù)據(jù)庫格式。
12) 使用場景
Pandas常見于數(shù)據(jù)分析、數(shù)據(jù)管理和數(shù)據(jù)可視化等使用場景。在眾多數(shù)據(jù)科學相關(guān)項目的數(shù)據(jù)準備階段,都能見到Pandas的廣泛使用[6]。而NumPy更常見于純粹的數(shù)值計算領(lǐng)域,尤其是其內(nèi)置的大量矩陣操作相關(guān)函數(shù)和方法,能夠大大簡化矩陣運算的編程工作量[7]。
13) 在機器學習和人工智能中的使用
在機器學習的過程中,通常可以分為數(shù)據(jù)準備和數(shù)據(jù)建模兩個階段。在先期的數(shù)據(jù)準備階段中,常常能夠看到Pandas大顯身手,高效完成數(shù)據(jù)的清洗和處理。而在人工智能的經(jīng)典應(yīng)用中,必須通過NumPy數(shù)組對圖形、視頻等對象進行矩陣化表示。只有經(jīng)過數(shù)組化表示后,才能作為輸入供TensorFlow或Scikit后續(xù)進一步使用。
5 結(jié)束語
本文通過對比Pandas和NumPy這兩個數(shù)據(jù)科學領(lǐng)域中常見的第三方庫,嘗試幫助相關(guān)研究者和工作人員迅速厘清二者之間的區(qū)別與聯(lián)系,從而能在自己的項目和工作中快速、準確地選擇恰當?shù)姆椒ê凸ぞ?,順利推進研究工作的開展。
參考文獻:
[1] 嵩天,禮欣,黃天羽.Python語言程序設(shè)計基礎(chǔ)[M].2版.北京:高等教育出版社,2017.
[2] 高鴻斌,申肖陽.Python數(shù)據(jù)分析技術(shù)綜述[J].邯鄲職業(yè)技術(shù)學院學報,2018,31(4):49-51.
[3] 趙軍,劉文婷.Python醫(yī)學數(shù)據(jù)分析入門[M].北京:人民郵電出版社,2022.
[4] 肖慧明.Python技術(shù)在數(shù)據(jù)可視化中的研究綜述[J].網(wǎng)絡(luò)信息工程,2021(13):87-89.
[5] 陳都,徐峰.淺談Python在創(chuàng)傷流行病學數(shù)據(jù)分析中的應(yīng)用[J].創(chuàng)傷外科雜志,2022,24(7):481-485.
[6] 田學成,韓寧.公安工作疫情流調(diào)大數(shù)據(jù)建模和安全分析[J].網(wǎng)絡(luò)安全與數(shù)據(jù)治理,2022,41(10):31-36.
[7] 胡孟柯.基于Numpy的離散Bayes網(wǎng)絡(luò)推理[J].電腦編程技巧與維護,2021(8):24-26.
【通聯(lián)編輯:謝媛媛】