使用sympy从字符串解析一系列公式

时间:2018-08-01 22:37:41

标签: sympy

我有一个pandas df,其中包含许多我想能够解析并最终解决的字符串公式。我遇到了parse_expr,最初似乎可以解决我的问题,但现在我不太确定。 示例字符串公式可能如下所示:

A = B + C; D = A*.2;
如果我有一个方程组,并且我可能没有正确使用它,

parse_expr似乎可以很好地工作。就目前情况而言,由于等号,parse_expr引发“我认为语法无效”错误。谁能说出有可能使用parse_expr解决此问题的方法,还是我应该尝试另一种方法?

2 个答案:

答案 0 :(得分:1)

parse_expr基于Python标记器,但具有多个扩展。这些扩展采用函数的形式,这些函数采用令牌列表,本地字典和全局字典,并返回修改后的令牌列表。这些作为元组传递到parse_expr,就像parse_expr(expression, transformations=(transformation1, transformation2, ...))一样。

仅查看sympy.parsing.sympy_parser子模块的source可能是最容易的,以查看现有的转换及其工作方式。其中的某些转换可能对您有用。在这种情况下,您需要一个将=令牌转换成其他东西的转换(实际上,convert_equals_sign子模块中已经有一个转换函数sympy_parser可以做到这一点)。假设您还想以某种方式处理*.

我还写了关于Python标记化的指南,在这里可能会有所帮助:https://www.asmeurer.com/brown-water-python

如果您的语法与Python的语法相距太远,那么使用parse_expr将是一个挑战,因为它仅适用于Python的令牌生成器。在这种情况下,您需要为自己的DSL生成自己的语法和解析器(例如,使用antlr),并将其解析为可以转化为SymPy表达式的内容。

答案 1 :(得分:0)

SymPy无法一次解析一堆用分号分隔的公式,因此需要首先分割字符串。假设所有公式中都包含=,则需要在=处再次对其进行拆分。解析=的每一面之后,您可以将它们与SymPy的方程对象Eq组合在一起;或以其他方式使用它们。

from sympy import S, Eq
str = "A = B + C; D = A*.2;"
result = [Eq(*map(S, f.split("="))) for f in str.split(";")[:-1]]

结果为[Eq(A, B + C), Eq(D, 0.2*A)]

我使用S,是sympify的缩写; parse_expr可以类似地使用,并且这里有一些不需要的选项。