我有两个numpy数组a, b和一个形式为s = "1.5 * b if 2*a > 7 else a + b"
的字符串
我想创建一个数组c,它将以一种有效的方式计算数组上的字符串。
期望行为的示例:
a = np.array([1, 4])
b = np.array([3, 1])
s = "1.5 * b if 2*a > 7 else a + b"
print(my_eval(a, b, s))
[4, 1.5]
我在想f = np.vectorize(eval(s)); map(a, b, f)
最好的方法是什么?表达式中的数组数量可以更大(但要有合理的限制)。
我不能说效率,但是您可以在函数定义模板字符串中使用给定的字符串表达式s
,使用exec
将其执行到本地字典中,为非ufunc表达式向量化它,然后在建议的my_eval
函数中调用它:
import numpy as np
def my_eval(s, a, b):
locals_dict = {}
# Generates source code to define a new function from the given string.
source = f"def f(a, b): return {s}"
# Executes the function definition script into locals_dict.
exec(source, globals(), locals_dict)
# Defines a vectorized version of the newly defined function.
f = np.vectorize(locals_dict["f"])
# Applies the function.
return f(a, b)
s = "1.5 * b if 2 * a > 7 else a + b"
a = np.array([1, 4]).astype(float)
b = np.array([3, 1]).astype(float)
c = my_eval(s, a, b)
print(c)
可以修改以处理可变数量的输入参数。例如,下面的代码可以处理多达26个不同的输入数组,每个数组对应字母表中的一个字母:
import numpy as np
from string import ascii_lowercase
def my_eval(s, *args):
locals_dict = {}
# Generates source code to define a new function from the given string.
params = ", ".join(list(ascii_lowercase[0:len(args)]))
source = f"def f(*args): {params} = args; return {s}"
# Executes the function definition script into locals_dict.
exec(source, globals(), locals_dict)
# Defines a vectorized version of the newly defined function.
f = np.vectorize(locals_dict["f"])
# Applies the function.
return f(*args)