在numpy数组上调用“lambdify”生成的多参数函数

2024-10-16 20:41:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我在SymPy中编写了一个表达式f,如代码所示,然后使用lambdify将其转换为一个函数。然后,我使用np.vectorize(f)对其进行矢量化,以便能够将其应用于numpy数组

import numpy as np
from math import exp
a = Symbol('a')
x = Symbol('x')
b = Symbol('b')
c = Symbol('c')

from sympy import *
f = exp(-(a+b+c)*x)*(4+exp(-(a+b)*x) -2*exp(-a*x) - 2*exp(-c*x))
f = lambdify([x,(a,b,c)], f)
vff = np.vectorize(f)

t = np.arange(0, 5, 0.01, dtype=np.float64)
y = vff(t, (1,1,1)) # (1,1,1) stands for (a,b,c)

但在执行此操作时,最后一行抛出以下错误

TypeError: _lambdifygenerated() missing 1 required positional argument: '_Dummy_191'.

我认为语法可能是错误的。我在网上搜索,但找不到正确的语法。谁能告诉我正确的语法吗


Tags: 函数代码fromimportnumpy表达式错误np
1条回答
网友
1楼 · 发布于 2024-10-16 20:41:28
In [8]: print(f.__doc__)                                                                                             
Created with lambdify. Signature:

func(x, arg_1)

Expression:

(exp(x*(-a - b)) + 4 - 2*exp(-c*x) - 2*exp(-a*x))*exp(x*(-a - b - c))

Source code:

def _lambdifygenerated(x, _Dummy_166):
    [a, b, c] = _Dummy_166
    return ((exp(x*(-a - b)) + 4 - 2*exp(-c*x) - 2*exp(-a*x))*exp(x*(-a - b - c)))

导入的模块:

f可以通过以下方式运行:

In [9]: f(np.arange(3),(1,1,1))                                                                                      
Out[9]: array([1.        , 0.13262366, 0.00861856])

由于f使用数组输入,我认为您不需要vectorized表单

如果我用一个参数调用vff,我会得到您的错误:

In [14]: vff(np.arange(3))                                                                                           
                                     -
...
TypeError: _lambdifygenerated() missing 1 required positional argument: '_Dummy_166'

对于2个参数,我得到一个不同的错误:

In [15]: vff(np.arange(3),(1,1,1))                                                                                   
                                     -
...
<lambdifygenerated-1> in _lambdifygenerated(x, _Dummy_166)
      1 def _lambdifygenerated(x, _Dummy_166):
  > 2     [a, b, c] = _Dummy_166
      3     return ((exp(x*(-a - b)) + 4 - 2*exp(-c*x) - 2*exp(-a*x))*exp(x*(-a - b - c)))

TypeError: 'numpy.int64' object is not iterable

这是因为vectorize将标量1作为第二个参数传递vectorize将标量元组传递给函数,而不是数组。它是从接受标量参数的函数设计的,而不是数组甚至元组。有一些方法可以解决这个问题,但请记住vectorize而不是一种速度工具

由于您不希望vectorize迭代(a,b,c)参数,我们可以“排除”它:

In [16]: vff = np.vectorize(f, excluded=[1])                                                                         

In [17]: vff(np.arange(3),(1,1,1))                                                                                   
Out[17]: array([1.        , 0.13262366, 0.00861856])

这与上面的f的工作原理相同。但速度要慢得多:

In [18]: timeit vff(np.arange(300),(1,1,1))                                                                          
5.29 ms ± 11.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [19]: timeit f(np.arange(300),(1,1,1))                                                                            
103 µs ± 41 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

vectorize比列表理解更慢:

In [20]: timeit np.array([f(i,(1,1,1)) for i in range(300)])                                                         
3.91 ms ± 6.17 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

相关问题 更多 >