【问题标题】:TypeError: return arrays must be of ArrayType using lambdify of sympy in pythonTypeError:返回数组必须是 ArrayType 在 python 中使用 sympy 的lambdify
【发布时间】:2017-02-04 21:38:42
【问题描述】:

我有以下代码:

x,y,z,t = var('x,y,z,t')
d = set([t])
rule = And(Or(x,y,z),t)
atoms = tuple(rule.atoms())
params = [True if i in d else False for i in atoms]
lam = lambdify(atoms, rule)
lam(*params)

抛出:

Traceback (most recent call last):
File "<pyshell#142>", line 7, in <module>
lam(*params)
File "<string>", line 1, in <lambda>
TypeError: return arrays must be of ArrayType

而且我不明白为什么,对于其他规则来说效果很好。

【问题讨论】:

    标签: python numpy lambda sympy


    【解决方案1】:

    更新:此错误已在 SymPy 1.2 中修复,请参阅 its release notes。如果您遇到此错误,请更新您的 SymPy 安装。


    这个非常棘手,而且令人惊讶。这是名为 lam 的 lambda 的文档字符串:

    <lambda> lambda _Dummy_22, _Dummy_23, _Dummy_24, _Dummy_25
        Created with lambdify. Signature:
    
        func(z, x, y, t)
    
        Expression:
    
        And(Or(x, y, z), t)
    

    到目前为止一切顺利。好吧,我已经注意到您的输入参数是自动选择的,您不知道它们的顺序。我会明确设置诸如lambdify((x,y,z,t),rule) 之类的顺序,但我不知道您的实际应用程序(我只是想我会注意这一点)。

    无论如何,在 sympy 中尝试它显然可以正常工作:

    >>> And(Or(False,False,False),True)
    False
    

    在我的 IPython 系统上,这是我得到的完整错误:

    ----> 1 lam(*params)
    
    /usr/lib/python3/dist-packages/numpy/__init__.py in <lambda>(_Dummy_34, _Dummy_35, _Dummy_36, _Dummy_37)
    
    TypeError: return arrays must be of ArrayType
    

    注意错误中的 numpy 路径。由于我安装了 numpy,lambdify 尝试将符号表达式映射到 numpy 函数。由于您的表达式中只有AndOr,我只能假设它们分别是numpy.logical_andnumpy.logical_or。但这是交易(为简单起见,回到香草 REPL):

    >>> import numpy as np
    >>> np.logical_or(False,False,False)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: return arrays must be of ArrayType
    

    糟糕,你的问题是:numpy 的逻辑运算符是二进制的! operator.and_ 也是如此:

    >>> import operator
    >>> operator.and_(False,False,False)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: op_and_ expected 2 arguments, got 3
    

    lambdify 用于将符号表达式转换为数值的标准逻辑运算符不接受两个以上的输入参数。在 numpy 案例中出现神秘错误消息的原因是二进制 ufunc logical_or 的第三个输入参数被解释为输出数组而不是第三个操作数,但在这个 sympy 上下文中,这完全出乎意料。

    我的建议是使用all/anynumpy.all/numpy.any 作为您的具体示例,作为lambdifymodules 关键字参数传递:

    >>> lam = lambdify(atoms, rule,modules={'And':all, 'Or':any})
    >>> lam(*params)
    False
    

    这允许您定义自己的函数,用于进行从符号到数字的映射。

    【讨论】:

    • 我的解决方案可能是错误的,我的积极结果是 4 分之一的胜利!由于.atoms 返回集(我做了一些测试以实现结果已关闭)。无论如何,你可能没有做不必要的工作。
    • @UrielEli 很遗憾听到这个消息:(感谢您的反馈!
    猜你喜欢
    • 2017-02-25
    • 2019-12-15
    • 2021-07-21
    • 2014-09-14
    • 1970-01-01
    • 1970-01-01
    • 2012-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多