微信公衆號:「Python讀財」
若有問題或建議,請公衆號留言
Pandas是Python中用於數據處理與分析的屠龍刀,想必你們也都不陌生,但Pandas在使用上有一些技巧和須要注意的地方,尤爲是對於較大的數據集而言,若是你沒有適當地使用,那麼可能會致使Pandas的運行速度很是慢。html
對於程序猿/媛而言,時間就是生命,這篇文章給你們總結了一些pandas常見的性能優化方法,但願能對你有所幫助!python
讀取數據是進行數據分析前的一個必經環節,pandas中也內置了許多數據讀取的函數,最多見的就是用pd.read_csv()
函數從csv文件讀取數據,那不一樣格式的文件讀取起來有什麼區別呢?哪一種方式速度更快呢?咱們作個實驗對比一下。數組
這裏採用的數據共59萬行,分別保存爲xlsx
、csv
、hdf
以及pkl
格式,每種格式進行10次讀取測試,獲得下面的結果。性能優化
能夠看到,對同一份數據,pkl
格式的數據的讀取速度最快,是讀取csv
格式數據的近6倍,其次是hdf
格式的數據,速度最慘不忍睹的是讀取xlsx
格式的數據(這僅僅是一份只有15M左右大小的數據集呀)。微信
因此對於平常的數據集(大多爲csv格式),能夠先用pandas讀入,而後將數據轉存爲pkl或者hdf格式,以後每次讀取數據時候,即可以節省一些時間。代碼以下:app
import pandas as pd #讀取csv df = pd.read_csv('xxx.csv') #pkl格式 df.to_pickle('xxx.pkl') #格式另存 df = pd.read_pickle('xxx.pkl') #讀取 #hdf格式 df.to_hdf('xxx.hdf','df') #格式另存 df = pd.read_hdf('xxx.pkl','df') #讀取
在使用agg
和transform
進行操做時,儘可能使用Python的內置函數,可以提升運行效率。(數據用的仍是上面的測試用例)ide
一、agg+Python內置函數函數
二、agg+非內置函數oop
能夠看到對 agg 方法,使用內置函數時運行效率提高了60%。性能
三、transform+Python內置函數
四、transform+非內置函數
對transform
方法而言,使用內置函數時運行效率提高了兩倍。
假設咱們如今有這樣一個電力消耗數據集,以及對應時段的電費價格,以下圖所示:
數據集記錄着每小時的電力消耗,如第一行表明2001年1月13日零點消耗了0.586kwh的電。不一樣使用時段的電費價格不同,咱們如今的目的是求出總的電費,那麼就須要將對應時段的單位電費×消耗電量。下面給出了三種寫法,咱們分別測試這三種處理方式,對比一下這三種寫法有什麼不一樣,代碼效率上有什麼差別。
#編寫求得相應結果的函數 def get_cost(kwh, hour): if 0 <= hour < 7: rate = 0.6 elif 7 <= hour < 17: rate = 0.68 elif 17 <= hour < 24: rate = 0.75 else: raise ValueError(f'Invalid hour: {hour}') return rate * kwh #方法一:簡單循環 def loop(df): cost_list = [] for i in range(len(df)): energy_used = df.iloc[i]['energy_kwh'] hour = df.iloc[i]['date_time'].hour energy_cost = get_cost(energy_used, hour) cost_list.append(energy_cost) df['cost'] = cost_list #方法二:apply方法 def apply_method(df): df['cost'] = df.apply( lambda row: get_cost( kwh=row['energy_kwh'], hour=row['date_time'].hour), axis=1) #方法三:採用isin篩選出各時段,分段處理 df.set_index('date_time', inplace=True) def isin_method(df): peak_hours = df.index.hour.isin(range(17, 24)) simple_hours = df.index.hour.isin(range(7, 17)) off_peak_hours = df.index.hour.isin(range(0, 7)) df.loc[peak_hours, 'cost'] = df.loc[peak_hours, 'energy_kwh'] * 0.75 df.loc[simple_hours,'cost'] = df.loc[simple_hours, 'energy_kwh'] * 0.68 df.loc[off_peak_hours,'cost'] = df.loc[off_peak_hours, 'energy_kwh'] * 0.6
測試結果:
能夠看到,採用isin()
篩選出對應數據後分開計算的速度是簡單循環的近606倍,這並非說 isin()
有多厲害,方法三速度快是由於它採用了向量化的數據處理方式(這裏的isin()
是其中一種方式,還有其餘方式,你們能夠嘗試一下) ,這纔是重點。什麼意思呢?
這裏簡單畫了個圖,你們能夠結合這個圖和代碼好好體會是一個一個處理快,仍是把能進行相同操做的分開而後批量處理快。
若是在你的數據處理過程涉及到了大量的數值計算,那麼使用numba
能夠大大加快代碼的運行效率,numba
使用起來也很簡單,下面給你們演示一下。(代碼處理不具備實際意義,只是展現一下效果)
首先須要安裝numba
模塊
>>>pip install numba
咱們用一個簡單的例子測試一下numba
的提速效果
import numba @numba.vectorize def f_with_numba(x): return x * 2 def f_without_numba(x): return x * 2 #方法一:apply逐行操做 df["double_energy"] = df.energy_kwh.apply(f_without_numba) #方法二:向量化運行 df["double_energy"] = df.energy_kwh*2 #方法三:運用numba加速 #須要以numpy數組的形式傳入 #不然會報錯 df["double_energy"] = f_with_numba(df.energy_kwh.to_numpy())
從測試結果來看,再次凸顯出向量化處理的優點,同時numba
對本來速度已經很快的向量化處理也能提升一倍多的效率。更多numba
的使用方法請參考numba的使用文檔。
參考資料:
一、https://pandas.pydata.org/pan...
二、https://realpython.com/fast-f...
三、https://www.cnblogs.com/wkang...
原創不易,若是以爲有點用,但願能夠隨手點個贊,拜謝各位老鐵。
掃碼關注公衆號「Python讀財」,第一時間獲取乾貨,還能夠加Python學習交流羣!!