1. 程式人生 > 實用技巧 >8-Pandas擴充套件之Pandas提升效能的方法(eval()、query())

8-Pandas擴充套件之Pandas提升效能的方法(eval()、query())

  使用Pandas得到阿布分佈功能進行運算是,經常需要建立臨時物件,這樣會佔用很大的記憶體和使用較長的計算時間。pandas為了解決效能問題,引入了eval()query()函式,他們都依賴Numexpr包,運算過程中不需要費力地配置中間陣列。

一、使用Pandas.eval()實現高效能運算

1、pandas中的函式eval()能夠將字串物件轉化為有效的表示式,進行求值運算並返回結果;

  一般地,運算簡單或DataFrame資料量較少之時不適用eval()函式,在DataFrame大於10000行時使用eval(),效能會得到明顯提升。

>>>import numpy as np
>>>import pandas as pd
>>>nrows=20000
>>>nclos=200
>>>df1,df2,df3,df4 = [pd.DataFrame(np.random.randn(nrows,nclos)) for i in range(4)]
>>>%timeit df1+df2+df3+df4
50.8 ms ± 3.11 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

>>>%timeit pd.eval('df1+df2+df3+df4')
23.6 ms ± 888 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

  其中:魔術命令%timeit可自動多次執行語句,產生一個較為精準的平均執行時間。

  使用np.allclose()比較兩個陣列是否完全相同,結果為True表示eval函式計算結果與普通Pandas計算結果一致。

>>>np.allclose(df1+df2+df3+df4,pd.eval('df1+df2+df3+df4'))
True

2、eval()支援的運算方式

  eval()函式支援多種運算方式,如:算數運算、比較運算和布林運算,同時也支援物件屬性與索引的表達方式;

  eval()函式目前還不支援函式條用,if條件語句,迴圈語句及更為複雜的運算。

3、DataFrame.eval()實現列間運算

>>>df.eval("sex=='female'and score_math>80")
0    False
1     True
2     True
3    False
4     True
5    False
6    False
7    False
8    False
dtype: bool

#新增列
>>> df.eval('sum_score = score_math + score_music',inplace=True)
>>> df
  class     sex  score_math  score_music  sum_score
0     A    male          95           79        174
1     A  female          96           90        186
2     B  female          85           85        170
3     C    male          93           92        185
4     B  female          84           90        174
5     B    male          88           70        158
6     C    male          59           89        148
7     A    male          88           86        174
8     B    male          89           74        163

#修改列
>>> df.eval('score_math = score_math +5')
  class     sex  score_math  score_music  sum_score
0     A    male         100           79        174
1     A  female         101           90        186
2     B  female          90           85        170
3     C    male          98           92        185
4     B  female          89           90        174
5     B    male          93           70        158
6     C    male          64           89        148
7     A    male          93           86        174
8     B    male          94           74        163

4、DataFrame.eval()使用區域性變數

 通過@符號使用Python的區域性變數,@符號表示其後緊隨的是一個變數名稱而不是列名稱,如下:

>>> add = pd.Series([1,2,3,4,5,6,7,8])
>>> df.eval('score_math+@add')
0    96.0
1    98.0
2    88.0
3    97.0
4    89.0
5    94.0
6    66.0
7    96.0
8     NaN
dtype: float64

二、DataFrame.query()方法

  query()可以實現查詢過濾的功能,其用於與DataFrame.eval()類似。

>>> df.query("score_math>85 & score_music>85")
  class     sex  score_math  score_music  sum_score
1     A  female          96           90        186
3     C    male          93           92        185
7     A    male          88           86        174

  注意:DtaFrame.eval()盡心相同運算時返回的是布林值