从字符串中解析出一个条件。

5

我有两个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)

有什么更好的方法吗?表达式中数组的数量可以更多(但受到合理限制)。


2
numpy 版本已经不支持 python2.x 超过 3 年了。使用 python2 的用户数量很少,无法进行测试。np.fromiter((eval(s) for a, b in zip(a1, b1)), dtype=float) 可以与重命名的数组(python3)一起使用。字符串中的代码不能与 np.arrays 一起使用。我认为没有简单的方法可以避免解析字符串。 - Michael Szczesny
1
我已经在print周围添加了括号,因为你们对此感到非常强烈 :) - LazyCat
请定义“最佳方式”。这是否意味着快速?简单?强大?Pythonic?除此之外,请定义可以接受或不接受的表达式类型(即表达式的语言)。例如:表达式中可以使用函数吗?可以使用其他运算符如除法/减法吗?是否允许子表达式等。等等。 - Jérôme Richard
1
问题在于数组的条件模糊不清,没有一个布尔结果,而是一组布尔值(您可以在stackoverflow的4300个帖子中了解更多信息(占所有numpy问题的4.3%?有趣))。 - Michael Szczesny
1
请修正问题标题中的“stRing”拼写,这将提高“可搜索性”。 - Nikolaj Š.
显示剩余3条评论
1个回答

0

我不能保证效率,但你可以在函数定义模板字符串中使用给定的字符串表达式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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接