sympy lambdify可以用来桥接numpy和Sympy之间的功能。然而,我找不到使用lambdify时存在的缺点。例如,我感兴趣的是将Max与sympy和numpy一起使用:
f = lambdify([x], Max(x, 1), 'numpy')
f(np.array([-1,0,1]))抛出ValueError:
ValueError: The argument '[-1, 0, 1]' is not comparable.另一方面,使用dunder方法的原油操作很好:
f = lambdify([x], Add(x, 1), 'numpy')
f(np.array([-1,0,1]))输出:
array([0, 1, 2])最后,我希望lambdify能够与包含渐近符号对象(或sympy.tensor.array.Array)的numpy数组一起工作:
a = symarray('a', (3,))
f = lambdify([x], Max(x, 1), 'numpy')
f(a)抛出TypeError:
TypeError: cannot determine truth value of Relational我的预期输出是:
array([Max(1, a_0), Max(1, a_1), Max(1, a_2)], dtype=object)当然,我可以使用列表理解来实现这一点。
发布于 2021-06-11 10:43:15
help(f)显示:
Help on function _lambdifygenerated:
_lambdifygenerated(x)
Created with lambdify. Signature:
func(x)
Expression:
Max(1, x)
Source code:
def _lambdifygenerated(x):
return (amax((1,x), axis=0))尝试将其应用于一维数组有几个问题。
In [62]: a
Out[62]: array([-1, 0, 1])首先,它尝试从(1,x)生成一个数组,导致出现ragged警告。
In [63]: f(a)
/usr/local/lib/python3.8/dist-packages/numpy/core/fromnumeric.py:87: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-63-730f2a0fa0b7> in <module>
----> 1 f(a)
<lambdifygenerated-4> in _lambdifygenerated(x)
1 def _lambdifygenerated(x):
----> 2 return (amax((1,x), axis=0))
<__array_function__ internals> in amax(*args, **kwargs)
....
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()然后,它从尝试比较a和1的错误中获得歧义,结果是一个布尔数组。
lambdify是一个从sympy到numpy的相对“愚蠢”的词典翻译器,很容易失败。
Add的代码是
def _lambdifygenerated(x):
return (x + 1)它是一个有效的numpy表达式。
您的symarray案例:
In [72]: a = symarray('a', (3,))
In [73]: a
Out[73]: array([a_0, a_1, a_2], dtype=object)同样,np.array((1,a))生成了一个参差不齐的数组。max.reduce正在将数组与标量进行比较。
Add的工作原理是对a数组的元素进行列表理解:
In [74]: g=lambdify([x], Add(x, 1), 'numpy')
In [75]: g(a)
Out[75]: array([a_0 + 1, a_1 + 1, a_2 + 1], dtype=object)但是我们不需要lambdify来做这件事:
In [83]: a+1
Out[83]: array([a_0 + 1, a_1 + 1, a_2 + 1], dtype=object)和A*A.T类型的计算:
In [89]: a*a[:,None]
Out[89]:
array([[a_0**2, a_0*a_1, a_0*a_2],
[a_0*a_1, a_1**2, a_1*a_2],
[a_0*a_2, a_1*a_2, a_2**2]], dtype=object)
In [90]: _.sum(axis=1)
Out[90]:
array([a_0**2 + a_0*a_1 + a_0*a_2, a_0*a_1 + a_1**2 + a_1*a_2,
a_0*a_2 + a_1*a_2 + a_2**2], dtype=object)您的Max可以通过frompyfunc应用于a
In [91]: f=np.frompyfunc(lambda x: Max(1,x),1,1)
In [93]: f(a)
Out[93]: array([Max(1, a_0), Max(1, a_1), Max(1, a_2)], dtype=object)这类似于:
In [94]: np.array([Max(1,x) for x in a])
Out[94]: array([Max(1, a_0), Max(1, a_1), Max(1, a_2)], dtype=object)使用相同的速度,但在使用broadcasting等时更具灵活性。
https://stackoverflow.com/questions/67928751
复制相似问题