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()尽心相同运算时返回的是布尔值

posted @ 2020-08-23 10:32  大脸猫12581  阅读(1260)  评论(1编辑  收藏  举报