这个答案深入研究了pd.eval , df.query和df.eval提供的各种特性和功能。
建立
示例将涉及这些DataFrame(除非另有说明)。
np.random.seed(0)
df1 = pd.DataFrame(np.random.choice(10, (5, 4)), columns=list('ABCD'))
df2 = pd.DataFrame(np.random.choice(10, (5, 4)), columns=list('ABCD'))
df3 = pd.DataFrame(np.random.choice(10, (5, 4)), columns=list('ABCD'))
df4 = pd.DataFrame(np.random.choice(10, (5, 4)), columns=list('ABCD'))
注意
在讨论的三个函数中, pd.eval是最重要的。 df.eval和df.query在引擎盖下调用pd.eval 。 行为和使用在三个功能中或多或少地保持一致,稍后将突出显示一些较小的语义变化。 本节将介绍所有三个函数共有的功能 - 包括(但不限于) 允许的语法,优先级规则和关键字参数。
pd.eval可以评估可以包含变量和/或文字的算术表达式。 这些表达式必须作为字符串传递。 所以, 要回答上述问题 ,你可以做到
x = 5
pd.eval("df1.A + (df1.B * x)")
有些事情需要注意:
整个表达式是一个字符串
df1 , df2和x引用全局命名空间中的变量,这些变量在解析表达式时由eval选取
使用属性访问器索引访问特定列。 你也可以使用"df1['A'] + (df1['B'] * x)"来达到同样的效果。
我将在下面解释target=...属性的部分中讨论重新分配的具体问题。 但是现在,这里有更简单的pd.eval有效操作pd.eval :
pd.eval("df1.A + df2.A") # Valid, returns a pd.Series object
pd.eval("abs(df1) ** .5") # Valid, returns a pd.DataFrame object
...等等。 条件表达式也以相同的方式受支持。 以下语句都是有效的表达式,将由引擎进行评估。
pd.eval("df1 > df2")
pd.eval("df1 > 5")
pd.eval("df1 < df2 and df3 < df4")
pd.eval("df1 in [1, 2, 3]")
pd.eval("1 < 2 < 3")
可以在文档中找到详细说明所有支持的功能和语法的列表。 综上所述,
除左移( << )和右移( >> )运算符之外的算术运算,例如, df + 2 * pi / s ** 4 % 42 - the_golden_ratio
比较操作,包括链式比较,例如2 < df < df2
布尔运算,例如, df < df2 and df3 < df4或not df_bool list和tuple文字,例如[1, 2]或(1, 2)
属性访问,例如, df.a
下标表达式,例如df[0]
简单的变量评估,例如pd.eval('df') (这不是很有用)
数学函数:sin,cos,exp,log,expm1,log1p,sqrt,sinh,cosh,tanh,arcsin,arccos,arctan,arccosh,arcsinh,arctanh,abs和arctan2。
本文档的这一部分还指定了不受支持的语法规则,包括set / dict文字,if-else语句,循环和理解以及生成器表达式。
从列表中可以看出,您还可以传递涉及索引的表达式,例如
pd.eval('df1.A * (df1.index > 1)')
解析器选择: parser=...参数
在解析表达式字符串以