談到數據分析,則離不開談及R語言及R語言與Python在數據分析領域孰優孰劣之爭。
首先R語言作為正統統計學軟體,數據分析則是其應有之義,因而相比於Python這個在數據分析領域的新起之秀,R語言算是與Matlab、SAS在同一起跑線上。
後發優勢畢竟是可觀的,當Python開始涉足數據分析領域時,其便漸漸形成了與R語言分庭抗禮的趨勢。而在這股勢力中,其主角及成員便是NumPy、pandas、matplotlib以及scipy。本文要簡單介紹的則是主力中的主力:NumPy與pandas。
誠然,R語言幾乎專注於統計分析,其第三方包無數,有著統計學的深度以及各學科統計分析應用的廣度,並且也在與Python的較量中不甘示弱。但是,有著更深的網際網路基因的Python畢竟要比更有統計學深度的R語言更受網際網路公司數據分析師的喜愛。
上圖展示了NumPy、pandas(以及matplotlib)的歷史總共下載量等信息。可以看出,兩者總共有過近80萬的下載量,如果按照市場價值計量,兩者合計價值近1500萬美元,但它們都可以免費使用。
縱然NumPy與pandas風靡於數據分析任務,人們對其的不足也多有指出,其中最主要的便是由於Python自身的動態語言特性而帶來的運行速度方面的損失,其次便是Python在大數據處理方面(數G甚至幾十上百G)的捉襟見肘。
對於前者,NumPy已經做了相當程度的優化,可以對大數組的數據進行高效處理。優化包括NumPy是在一個連續的內存塊中存儲數據,獨立於其他Python內置對象,如此便可以加速數據索引的速度。其次,NumPy調用了大量的用C語言編寫的算法庫,使得其可以直接操作內存,不必進行Python動態語言特性所含有的前期類型檢查工作,從而大大提高了運算速度。最後,NumPy所有獨有的可以在整個數組上執行複雜的計算也能夠大幅提高運算效率(基於NumPy的算法要比純Python快10到100倍,甚至會快更多)。
而對於後者,經過合理的優化,Python處理幾個G的數據綽綽有餘,至於幾十G也勉強可以,而上百G的數據這就算是Hadoop與Spark系列的任務,不是Python的NumPy與pandas可以應付的,也不是R語言某個第三方包可以處理的。
NumPy除了在相當程度上優化了Python計算過程,其自身還有較多的高級特性,如指定數組存儲的行優先或者列優先、廣播功能從而快速的對不同形狀的矩陣進行計算、ufunc類型的函數可以使得我們丟開循環而編寫出更為簡潔也更有效率的代碼、使用開源項目Numba編寫快速的NumPy函數,而Numba則是可以利用GPU進行運算的。
雖然NumPy有著以上的種種出色的特性,其本身則難以獨支數據分析這座大廈,這是一方面是由於NumPy幾乎僅專注於數組處理,另一方面則是數據分析牽涉到的數據特性眾多,需要處理各種表格和混雜數據,遠非純粹的數組(NumPy)方便解決的,而這就是pandas發力的地方。
pandas 這個名稱來源於panel data(面板數據),從而可見其要處理的數據是多維度的而非單維度。pandas 含有使數據清洗和分析工作變得更快更簡單的數據結構與操作工具。經常是和其他工具一起使用,如數值計算工具NumPy和SciPy,分析庫statsmodels與scikit-learn,以及數據可視化庫matplotlib。其中NumPy則是構建pandas的基礎,後者大量借鑑了NumPy編碼風格。
如果用做一餐飯來比喻,pandas於處理數據方面的功用則相當於將米洗好,將菜摘好洗好以及切好的過程,至於入鍋添油加醋,鍋鏟搗騰,做成一道菜則是依靠statsmodels、scikit-learn和matplotlib的功能。
pandas功能特性廣泛,其包含的函數類型也眾多,數據結構有Series與DataFrame,函數類型有索引函數、匯總函數、加載以及保存眾多文件格式函數、與資料庫交互函數、字符串處理函數、缺失數據處理函數、合併重塑軸向旋轉表格型數據函數、簡單的繪圖函數、數據聚合(groupby)分組運算(apply)函數、透視表交叉表函數以及時間序列處理方面的各種函數。
由於類型過多,不便歷述,下面便從上述選擇幾個對象來說。其中Series處理的是單列數據,其格式如下所示:
0,1,2,3是索引,4,7,-5,3是值,索引可以自行指定的。
而DataFrame是一個表格型的數據結構,它含有一組有序的列,每一列可以是不同的值類型(數值、字符串布爾值等),DataFrame既有行索引也有列索引,可以被看做是由Series組成的字典(共用同一個索引),如:
pandas可以讀取較多類型的文件格式,從簡單的txt、csv、json到excel,hdf5、pickle再到sas、sql、stata等等文件格式都有得以支持。在讀取數據時,函數會使用到若干技術將數據轉換成DataFrame格式,如索引、類型推斷和數據轉換、日期解析、迭代與不規整數據問題等。
至於pandas與資料庫交互,它可以通過特定的第三方包實現將SQL Server、 PostgreSQL和MySQL資料庫中的數據加載到DataFrame中,然後進行各種處理分析。
pandas自帶的繪圖函數較為簡陋,只有簡單的plot函數,不過Series或者DataFrame格式的數據可以與matplotlib以及seaborn等繪圖工具結合以繪製各類精緻的圖例。
由於表格型數據往往是有類別屬性的,如班級學生的各科成績,班級、學生性別等都是類別屬性,所以數據聚合(groupby)分組運算(apply)函數則是相當重要的,其使用示例如下:
最後分享的是pandas的時間序列類函數,可以說是pandas讓處理時間序列數據變得得心應手。第三方包datetime與dateutil能夠將識別與處理多種時間格式,pandas自身可以生成指定頻率的DatetimeIndex,也可以處理時區信息。其移動窗口函數則是大大方便了時間序列分析,使得建立各種AR、MA、ARMA、ARIMA等等時間序列模型方便快捷,而這正是R語言的領地。
Python因為有了NumPy與pandas而不同於Java、C#等程序語言,Python也因為NumPy與pandas而又一次的煥發了光彩。NumPy與pandas也許多少借鑑了R語言的特性與功能,但它也的確做的了在某些方面青出於藍勝於藍。
歡迎有興趣的小夥伴通過官網聯繫我司。