处理数据时,使用eval()与query()方法,运算速度将提升一倍!

处理数据时,使用eval()与query()方法,运算速度将提升一倍!前言:下面来聊一聊,pandas的高性能运算,eval。它们可以让用户直接运行C语言速度,不需要费力的配置中间数组,它们都依赖于Numexpr程

大家好,欢迎来到IT知识分享网。

处理数据时,使用eval()与query()方法,运算速度将提升一倍!

前言:

下面来聊一聊,pandas的高性能运算,eval()与query()。它们可以让用户直接运行C语言速度,不需要费力的配置中间数组,它们都依赖于Numexpr程序包。

pandas.eval()的高性能运算

Pandas的eval()函数,用字符串代数式实现了DataFrame的高性能运算。

生成数据:

import pandas as pd
nrows, ncols= 100000, 100
rng= np.random.RandomState(42)
df1, df2, df3, df4= (pd.DataFrame(rng.rand(nrows, ncols))
for i in range(4))

一般的方法:

计算四个DataFrame的和

%timeitdf1+df2+df3+df4
77.5 ms ± 5.08 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

pandas.eval()方法:

计算四个DataFrame的和

%timeitpd.eval('df1 + df2 + df3 + df4')
40.3 ms ± 1.38 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

通过观察我们发现eval()方法比一般的方法快了一倍,而且消耗的内存也少。

pandas.eval()支持哪几种运算符?

(1) 算术运算符

pandas.eval()支持所有的算术运算符;

df1, df2, df3, df4, df5= (pd.DataFrame(rng.randint(0, 1000, (100, 3)))
 foriinrange(5))
result1= -df1*df2/(df3+df4) -df5
result2= pd.eval('-df1 * df2 / (df3 + df4) - df5')
np.allclose(result1, result2)
True

用np.allclose()看输出的结果是否一样。

(2) 比较运算符

pandas.eval()支持所有的比较运算符,包括链式代数式;

result1= (df1<df2) &(df2<= df3) &(df3!= df4)
result2= pd.eval('df1 < df2 <= df3 != df4')
np.allclose(result1, result2)
True

(3) 位运算符

pandas.eval()支持 &(与)和 |(或)等位运算符;

result1= (df1<0.5) &(df2<0.5) |(df3<df4)
result2= pd.eval('(df1 < 0.5) & (df2 < 0.5) | (df3 < df4)')
np.allclose(result1, result2)
True

还支持布尔类型在代数式中使用 and 和 or 等位运算符;

result3= pd.eval('(df1 < 0.5) and (df2 < 0.5) or (df3 < df4)')
np.allclose(result1, result3)
True

(4) 对象属性与索引

pandas.eval()可以通过obj.attr语法获取对象属性,通过obj[index]语

法获取对象索引;

result1= df2.T[0] +df3.iloc[1]
result2= pd.eval('df2.T[0] + df3.iloc[1]')
np.allclose(result1, result2)
True

目前 pandas.eval()还不支持函数调用、条件语句、循环以及更复杂的运算。如果你想要进行这些运算,可以借助 Numexpr 来实现。

DataFrame.eval()列间运算

由于pd.eval()是 Pandas的顶层函数,因此,DataFrame也有一个eval()方法,可以做类似的运算。

DataFrame.eval()方法的好处,就是可以借助列名称进行运算;

df= pd.DataFrame(rng.rand(1000, 3), columns=['A', 'B', 'C'])
df.head()

处理数据时,使用eval()与query()方法,运算速度将提升一倍!

pandas.eval()方法计算列:

result1= (df['A'] +df['B']) /(df['C'] -1)
result2= pd.eval("(df.A + df.B) / (df.C - 1)")
np.allclose(result1, result2)
True

DataFrame.eval() 方法通过列名称计算列

result3= df.eval('(A + B) / (C - 1)')
np.allclose(result1, result3)
True

DataFrame.eval(),新增列;

除了运算功能,DataFrame.eval()还可以创建新的列。列如:DataFrame.eval()创建一个新的列 ‘D’,然后赋给它其他列计算的值。

df.eval('D = (A + B) / C', inplace=True)
df.head()

处理数据时,使用eval()与query()方法,运算速度将提升一倍!

DataFrame.eval(),修改已有的列;

df.eval('D = (A - B) / C', inplace=True)
df.head()

处理数据时,使用eval()与query()方法,运算速度将提升一倍!

DataFrame.eval(),使用局部变量;

DataFrame.eval()方法,还支持@符号使用Python的局部变量。

column_mean= df.mean(1)
result1= df['A'] +column_mean
result2= df.eval('A + @column_mean')
np.allclose(result1, result2)
True

@ 符号表示“这是一个变量名称而不是一个列名称”需要注意的是,@符号只能在DataFrame.eval()方法中使用,而不能在pandas.eval()函数中使用, 因为 pandas.eval()函数只能获取一个(Python)命名空间的内容。

DataFrame.query()方法

DataFrame基于字符串代数式的运算实现了另一个方法。

过滤运算;

result1= result1= df[(df.A<0.5) &(df.B<0.5)]
result2= df.query('A < 0.5 and B < 0.5')
np.allclose(result1, result2)
True

query()方法,同样也支持用@符号引用局部变量;

Cmean= df['C'].mean()
result1= df[(df.A<Cmean) &(df.B<Cmean)]
result2= df.query('A < @Cmean and B < @Cmean')
np.allclose(result1, result2)
True
处理数据时,使用eval()与query()方法,运算速度将提升一倍!

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/48280.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信