大家好,欢迎来到IT知识分享网。
前言:
下面来聊一聊,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()
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()
DataFrame.eval(),修改已有的列;
df.eval('D = (A - B) / C', inplace=True) df.head()
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
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/48280.html