pandas性能提升之避免對小數據量使用pandas內置函數

       pandas本身就是面向數據分析的,而且是面向大數據分析的,所以其內置函數本身在設計上相比於一些python原生的操作就會繁雜一些,這也是爲了功能性的考慮。所以,這就導致了其內置函數就像高速火車,而python的原生操作就像超跑,超跑在速度上是具有優勢的,但是在功能性上是比不上高速火車的。所以,理論上,如果可以用python的原生操作實現,那麼總是可以更快的,畢竟內置函數很多也是用原生操作封裝好的接口而已;但是在代碼的簡潔性上以及重用性上就會更差,而且有時候我們自己的實現方式並不是最優的,即我們以爲我們是在用超跑,其實自己造出來的只是自行車而已。

       所以,內置函數的優勢在於,其功能性比較強,所以相比於超跑其起步較慢;由於直接是一個接口,可以讓代碼更加的簡潔,重要的是,內置函數的往往也是在滿足功能性的前提下,是最優的實現方式;其弱點在於,因爲功能性而犧牲了性能,所以我們理論上總是可以用python的原生結構和操作更快的實現,因爲當我們用原生方式實現時,實際上功能性是很單一的,所以性能也會更好,當然,內置函數的優點也就是python原生方式的缺點,因此,對於是用內置函數還是原生方式實現,需要根據不同的情形去權衡。

       pandas中,對於小數據量的操作,要儘量避免使用大部分內置函數(並非絕對,但絕對是大部分),轉而使用python的輕量級的原生的操作,即用python原生的數據結構和數據之間的加減乘除等操作實現,特別是在這種情形下:對一個具有幾十萬行的DataFrame進行逐行的操作,這時由於每行的數據量往往較小,故不宜使用pandas內置函數,每行的一點點性能的損失經過幾十萬行的累加放大,就可以使得整個程序的性能顯著下降。但是,如果我們是對列進行操作,這時數據量足夠的大,由於函數功能性帶來的性能損失是固定的,不隨着數據量變化而變化,因此,這時起步的耽擱的時間相比於長途旅行來說就顯得微不足道了。

       對於大數據量的操作,我們要儘量使用內置函數,因爲內置函數的封裝往往是相當底層的,我們用最優的原生方式實現往往比較繁瑣;此外,我們要儘量使用內置函數的另一個重要的理由其實在於:pandas中的內置函數是基於numpy,而numpy底層很多是c實現的,所以相比於python原生操作在性能上具有質的提升,這相當於,高速火車變成了飛機,雖然起步還是略慢,但是中間的運行速度是遠超超跑的。所以,大數據量的操作,主要時間就不是在起步上了,而是在中間的執行速度上。

       上述說明可從下面的例子中看出,對於極少的數據,原生的+優於np.sum。

import time
import pandas as pd
import numpy as np
 
df=pd.DataFrame(np.arange(800000).reshape(200000,4),columns=list('abcd'))
t1=time.time()
s1=df.apply(lambda x:x['a']+x['c']+x['b']+x['d'],axis=1)
t2=time.time()
print(t2-t1)
 
# output: 17.57075548171997

t5=time.time()
s1=df.apply(np.sum,axis=1)
t6=time.time()
print(t6-t5)
 
# output: 39.55056023597717

 

發佈了143 篇原創文章 · 獲贊 83 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章