我正在尝试使用 sp.Max(x, 0) 对大型解析表达式进行 lambdify。我想使用 numpy 来矢量化我的计算,因此 x 将是一个数组。我需要 x 和 0 的元素最大值。不过,sympy 默认将 sp.Max 更改为 np.amax。它沿轴找到最大值,这不是我需要的。lambdify 中的“modules”关键字无法按预期工作。我试过:
import numpy as np import sympy as sp arr = np.array([1, 2, 3]) expr = sp.sin(x) + sp.Max(x, 0) f = sp.lambdify(x, expr, modules=[{'Max': np.maximum}, 'numpy']) # docs say, priority of modules matters help(f)
它给出:
Help on function _lambdifygenerated: _lambdifygenerated(x) Created with lambdify. Signature: func(x) Expression: sin(x) + Max(0, x) Source code: def _lambdifygenerated(x): return (sin(x) + amax((0,x))) Imported modules:
由于某种原因,sp.Max 更改为 amax。
如果“numpy”未包含在“模块”列表中,它将跳过所有其他函数。我也尝试过在列表中交换 dict 和“numpy”,但没有帮助。请澄清一下,出了什么问题?这是 sympy 中的错误吗?
当使用lambdify创建用于矢量化的 numpy 函数时,经常会出现一些细微的问题,尤其是当变量(x)和常量(0)混合在一起时。
lambdify
x
0
在这种情况下,sp.max假设其所有可能的参数都是单个值。np.amax获取一个扁平数组的最大值。np.maximum获取两个数组的元素最大值。这里的问题是常量0不会自动扩展为 numpy 数组。
sp.max
np.amax
np.maximum
我的解决方法是sp.max使用基于的自定义函数进行替换sp.Piecewise。请注意,如果 有超过 2 个参数,则需要一个单独的函数sp.max。
sp.Piecewise
import numpy as np import sympy as sp from sympy.abc import x def sympy_max2(a, b): return sp.Piecewise((b, a < b), (a, True)) arr = np.array([11, 22, 33, -1, -2]) expr = sp.sin(x) + sympy_max2(0, x) f = sp.lambdify(x, expr, modules=['numpy']) print(f(arr)) # [10.00000979 21.99114869 33.99991186 -0.84147098 -0.90929743]