Matlab symvar 函数的 Python 替代品

发布于 2024-12-11 11:55:56 字数 500 浏览 0 评论 0原文

Matlab 有一个名为 symvar 的函数,它接受一个字符串表达式(通常包含有效的 matlab 指令)并标识变量。然后可以处理/替换它们以评估表达式。

例如:

symvar('cos(pi*x - beta1)')

returns

{'beta1';'x'}

Python中有类似的功能吗?

这是我如何使用它的示例: 假设我有一个 DataFrame DF(在本例中我指的是 pandas 模块,但我想这也适用于 numpy recordarray),包含一组变量,例如 A、B、C。我希望我的用户能够通过指定类似

add_field(DF,"D=log(A)+C*3") 之类的

内容来添加附加列在内部,该函数会将 A、C 和 D 识别为变量,提取 A 和从数据帧中提取 D,执行计算(使用 eval 或类似方法),然后将 D 作为新列添加到数据帧中。

谢谢

Matlab has a function called symvar, that takes a string expression, usually containing valid matlab instructions, and identifies variables. These can then be handled/replaced in order to evaluate the expression.

For example:

symvar('cos(pi*x - beta1)')

returns

{'beta1';'x'}

Is there a similar functionality in Python?

Here is an example of how I would use this:
say I have a DataFrame DF (in this case I am referring to the pandas module, but I guess this also applies to numpy recordarray), containing a set of variables, eg A,B,C. I want my user to be able to add an additional column by specifying something like

add_field(DF,"D=log(A)+C*3")

Internally, the function would recognize A, C and D as variables, extract A and D from the dataframe, perform the calculation (using eval or similar), and then add D as new column to the dataframe.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

画离情绘悲伤 2024-12-18 11:55:56

从 Python 表达式获取标识符列表的一种方法是使用 ast 模块:

import ast
class IdentifierExtractor(ast.NodeVisitor):
    def __init__(self):
        self.ids = set()
    def visit_Name(self, node):
        self.ids.add(node.id)
extractor = IdentifierExtractor()
extractor.visit(ast.parse("cos(pi*x - beta1)"))
print extractor.ids

prints

set(['x', 'cos', 'pi', 'beta1'])

您还可以排除在 math 模块(或任何其他命名空间)中定义的名称):

print extractor.ids - set(vars(math))

打印

set(['beta1', 'x'])

(请注意,我仍然不知道这一切可能有什么用......)

One way to get the list of identifiers from a Python expression is to use the ast module:

import ast
class IdentifierExtractor(ast.NodeVisitor):
    def __init__(self):
        self.ids = set()
    def visit_Name(self, node):
        self.ids.add(node.id)
extractor = IdentifierExtractor()
extractor.visit(ast.parse("cos(pi*x - beta1)"))
print extractor.ids

prints

set(['x', 'cos', 'pi', 'beta1'])

You could also exclude the names defined in the math module (or any other namespace):

print extractor.ids - set(vars(math))

prints

set(['beta1', 'x'])

(Note that I still don't have any clue what all this might be useful for...)

不乱于心 2024-12-18 11:55:56

为此,我会尝试将用户表达式转换为 Python 源代码,然后对其调用 evaleval 将负责变量替换。对于简单的用例,无需执行任何操作即可将用户表达式“转换”为 Python 源代码。

expression = "cos(pi*A + B)" # (user input)
bulitin_vars = {
    "pi": math.pi,
    "e": math.e,
    "cos": numpy.cos,
}
data_vars = {col_name]: df[col_name] for col_name] in df.columns}
all_vars = {**builtin_vars, **data_vars}
result = eval(expression, all_vars)

这是一个很好的设计,因为用户可以在其表达式中使用所有 Python 语言(可以使用列表、字典等)。如果您手动编写简单的表达式语言,它可能会不太完整,尤其是在错误处理方面。只需确保在 eval 中捕获错误并以某种方式向用户显示它们即可。

For this, I would try to convert the user expression as Python source code and then call eval on it. eval will take care of variable substitutions. For simple use-cases, nothing needs to be done to "convert" the user expression to Python source code.

expression = "cos(pi*A + B)" # (user input)
bulitin_vars = {
    "pi": math.pi,
    "e": math.e,
    "cos": numpy.cos,
}
data_vars = {col_name]: df[col_name] for col_name] in df.columns}
all_vars = {**builtin_vars, **data_vars}
result = eval(expression, all_vars)

This is a nice design because the user has all of Python available for use in their expression (can use lists, dicts, etc.). If you hand-code a simple expression language, it will likely be less complete, especially with respect to error-handling. Just make sure you catch errors in the eval and show them to the user somehow.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文