python資料分析程式碼優化小結
過去一段時間在對python版本的評分卡模型做效率優化。之前的版本已經實現了所有功能但是速度實在太慢。13W的資料量包含130個特徵(其中30個連續值)使用原來的版本需要花費將近兩小時的時間才能夠計算出所有特徵值的IV。這個效率實在是。。。。
經過優化,現在可以將時間控制在5s左右。可以說是相當不錯了。
接下來小結一下關於python程式碼方面優化的方法。(演算法方面沒啥可改的就是簡單的統計數)
環境
python版本:python 2.7
包:numpy和pandas
效率優化方法
pandas一些優化的細節
使用DataFrame.concat()代替DataFrame.append()
將資料處理好儲存為list,再將list用concat連線。
這種方法的效率比直接在DataFrame後面使用append。效率要高出30%~50%- Dataframe的append效能很低,如果我們知道未來表的條目,預先分配好空間,將來直接向裡面填入內容會快不少
# 例子 # 預先分配好記憶體空間 outdf = pd.DataFrame(pd.np.empty((output_index_num, len(indf.columns))) * pd.np.nan, columns = indf.columns) # 用for迴圈來補充資料 for outindex in
- pandas中loc,iloc,ix,at這幾種方法的選擇
%timeit outdf.loc[0] = indf.loc[0] 100 loops, best of 3: 11.7 ms per loop %timeit outdf.iloc[0] = indf.iloc[0] 100 loops, best of 3: 11.4 ms per loop
loc,iloc,ix速度相似,可是at卻快了將近1000倍。
可惜的是at只能選擇某個單元而不是整行。- 平行計算
這個所有加速效率中最簡單效果也是最穩定的方法了。
python中有幾種多程序的方法。
1.multiprocessing
2.joblib中的Parallel,delayed
# joblib例子
from joblib import delayed, Parallel
def square(x): return x*x
values = Parallel(n_jobs=NUM_CPUS)(delayed(square)(x) for x in range(1000))
# Parallel(n_jobs=cpu核心數)
#(delayed(函式名)(函式引數列表) for x ...)
2. python垃圾自動回收機制
Python常用的垃圾回收(GC)演算法有這幾種引用計數(Reference Count)、Mark-Sweep、Copying、分代收集。在Python中使用的是引用計數。
工作原理:為每個記憶體物件維護一個引用計數。
因 此得知每次記憶體物件的建立與銷燬都必須修改引用計數,從而在大量的物件建立時,需要大量的執行修改引用計數操作(footprint),對於程式執行過程 中。
這個方法大概能夠提高10%左右的效率。
- 使用pypy編譯器
PyPy是用RPython(CPython的子集)實現的Python,根據官網的基準測試資料,它比CPython實現的Python要快6倍以上。快的原因是使用了Just-in-Time(JIT)編譯器,即動態編譯器,與靜態編譯器(如gcc,javac等)不同,它是利用程式執行的過程的資料進行優化。由於歷史原因,目前pypy中還保留著GIL,不過正在進行的STM專案試圖將PyPy變成沒有GIL的Python。
如果python程式中含有C擴充套件(非cffi的方式),JIT的優化效果會大打折扣,甚至比CPython慢(比Numpy)。所以在PyPy中最好用純Python或使用cffi擴充套件。
由於numpy和pandas底層許多方法由C語言實現,所以在實際使用過程中,pypy編譯的效率反而變得更加慢。可以看出如果對於pure python程式碼,使用pypy編譯可以得到效率極大的提高。
使用numba加速
numba中加速的方法和pypy加速的方法是相同的。就是使用JIT來提高python指令碼語言的執行速度。缺點也相同,對於python程式中含有C擴充套件(非cffi的方式)效果反而不夠好。
使用Cython來進行加速
這個就需要有C語言開發的基礎了。可以很方便的將一些函式使用C語言的方法進行重寫,從而加快程式碼的執行效率。
使用向量化來操作pandas
這個效率提高特別高。在我的程式碼中使用這個方法將效率提高了700+倍。相同的資料量下時間花費也從原來的接近兩小時降低到只要10s左右。可見這個效率提升之恐怖。
具體操作請檢視參考”優化Pandas程式碼執行速度入門指南”
儲存優化方法
第一種方法是對pandas中數值型資料的降級。比如將int32轉為int16.float64轉為float32.
第二種方法是將objcet型別轉換為category型別。這個是最節約空間的方法。具體優化方法請見參考 “用pandas處理大資料———減少90%記憶體消耗的小貼士”
如何提高pandas讀取速度
可以檢視參考 ” 使用Python Pandas處理億級資料”
這裡小結一下這段時間嘗試的方法,同時也對python的優化有了一些認識。希望對大家有一點借鑑作用。