TypeError:在python中使用sympy的lambdify返回数组必须是ArrayType [英] TypeError: return arrays must be of ArrayType using lambdify of sympy in python

查看:141
本文介绍了TypeError:在python中使用sympy的lambdify返回数组必须是ArrayType的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

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

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

And I can't understand why, for other rules it works great.

推荐答案

更新:此错误已在SymPy 1.2中修复,请参见其发行说明.如果遇到此错误,请更新您的SymPy安装.

Update: This bug was fixed in SymPy 1.2, see its release notes. If you are experiencing this bug update your SymPy installation.

这很棘手,令人惊讶.这是您的lambda的文档字符串,名为 lam :

This one's pretty tricky, and surprising. Here's the docstring of your lambda named lam:

<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),但是我不知道您的实际应用程序(我只是以为我会注意到这一点)

So far so good. Well, I'd already note that your input arguments are being chosen automatically, and you don't know their order. I'd explicitly set an order such as lambdify((x,y,z,t),rule), but I don't know your actual application (I just thought I'd note this).

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

Anyway, trying it within sympy obviously works fine:

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

在IPython中的系统上,这是我得到的全部错误:

On my system within IPython, this is the full error I get:

----> 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函数.由于您的表达式中仅包含 And Or ,因此我只能假定它们是 numpy.logical_and numpy.logical_or .但这是交易(为简单起见,回到原始的REPL):

Note the numpy path in the error. Since I have numpy installed, lambdify tries to map the symbolic expression to numpy functions. Since you only have And and Or in your expression, I can only assume these are numpy.logical_and and numpy.logical_or, respectively. But here's the deal (going back to the vanilla REPL for simplicity):

>>> 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 _ :

Oops, there's your problem: numpy's logical operators are binary! The same goes for 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 的第三个输入参数被解释为输出数组,而不是第三个操作数,但是在这种有症状的上下文中,这完全是意外

The standard logical operators which lambdify uses to convert your symbolic expression to numerical don't accept more than two input arguments. The reason for the cryptic error message in the numpy case is that the third input argument of the binary ufunc logical_or is interpreted as an output array instead of a third operand, but in this sympy context this is entirely unexpected.

我的建议是为您的特定示例使用 all/any numpy.all/numpy.any ,作为 modules 关键字传递 lambdify 的参数:

My suggestion is to use all/any or numpy.all/numpy.any for your specific example, passed as the modules keyword argument of lambdify:

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

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

This allows you to define your own functions that are used to do the mapping from symbolic to numerical.

这篇关于TypeError:在python中使用sympy的lambdify返回数组必须是ArrayType的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆