使用lamdify添加两个numpy数组 - 将表达式作为函数参数传递

时间:2017-01-26 13:32:47

标签: python numpy sympy

我有这段代码:

import numpy as np
import sympy
from sympy import symbols
from sympy.utilities.autowrap import ufuncify
from sympy.utilities.lambdify import lambdify


def test(expr,a,b):

    a_var, b_var = symbols("a b")
    #f = ufuncify((a_var, b_var), expr, backend='numpy')
    f = lambdify( (a_var, b_var), expr, 'numpy')
    return f(a_var, b_var)


a = np.array([2,3])
b = np.array([1,2])
expr = a + b

print(test(expr, a, b))

给我:

../anaconda3/envs/python3/lib/python3.6/site-packages/sympy/core/sympify.py:282: VisibleDeprecationWarning: using a non-integer number instead of an integer will result in an error in the future
  rational=rational) for x in a])

   File "<string>", line 1
 lambda _Dummy_52,_Dummy_53: ([3 5])                                
 SyntaxError: invalid syntax

如果我使用ufuncify:

...

TypeError: unhashable type: 'numpy.ndarray'

During handling of the above exception, another exception occurred:
...

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

======更新================

我找到的一个解决方案是像字符串一样使用expr,然后在函数内使用sympify

data_a = np.array([2,3])
data_b = np.array([1,2])
expr = "data_a + data_b"


def test(expr,data_a, data_b):

        a, b = symbols("data_a data_b")
        expr = sympify(expr)
        f = lambdify( (a, b), expr, 'numpy')
        return f(data_a, data_b)

我正在服用:

[3 5]

但是如何避免将表达式用作字符串?

1 个答案:

答案 0 :(得分:1)

lambdify将SymPy表达式转换为NumPy函数。您正在尝试将NumPy数组转换为NumPy函数。 lambdify的参数需要是SymPy对象。

你想要像

这样的东西
a_var, b_var = symbols("a b")
expr = a_var + b_var
f = lambdify((a_var, b_var), expr, 'numpy')

然后你会得到

>>> a = np.array([2,3])
>>> b = np.array([1,2])
>>> f(a, b)
array([3, 5])

lambdify的基本代码流是SymPy expression =&gt; NumPy功能。为了让你的头脑和代码保持清晰,你应该从SymPy开始,并操纵表达式,直到你有一个lambdified函数。然后将它与您的NumPy数据一起使用。从定义符号名称开始。然后,您可以根据这些符号定义表达式,而不使用字符串(例如,如上所述)。一旦有了表达式和符号,就可以创建一个lambdified函数。此时,您将NumPy数组传递给函数。我建议为SymPy符号/表达式和NumPy数组使用不同的变量名,这样它们就不会混淆。我还建议使用与符号相同的变量名作为符号名称本身,这样当您打印表达式时,它将与您编写的完全一样(例如,如果您print(expr),则会得到{{1}这就是你要写的a + b}。

在更新的示例中,您可以使用

expr

请注意我如何从这些符号创建SymPy符号和SymPy表达式。然后我贬低它。一旦它被lambdified,我有lambdified函数(a, b = symbols("a b") expr = a + b f = lambdify((a, b), expr, 'numpy') data_a = np.array([2,3]) data_b = np.array([1,2]) f(data_a, data_b) )。此时,我根本不再使用SymPy,只是使用NumPy数组(数据)和lambdified函数f