Numpy Sympy lambdify最大可操作性
Sympy可用于连接numpy和Sympy之间的功能。但是,我没有发现使用lambdify时存在哪些缺点。例如,我有兴趣将Max与sympy和numpy一起使用:Numpy Sympy lambdify最大可操作性,numpy,sympy,Numpy,Sympy,Sympy可用于连接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 = lamb
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符号对象的numpy数组(或sympy.tensor.array.array
):
抛出类型错误:
TypeError: cannot determine truth value of Relational
我的预期产出是:
array([Max(1, a_0), Max(1, a_1), Max(1, a_2)], dtype=object)
当然,我可以使用列表理解来实现这一点。帮助(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))
尝试将此应用于1d阵列有两个问题
In [62]: a
Out[62]: array([-1, 0, 1])
首先,它尝试从(1,x)
生成一个数组,从而产生“不规则数组”警告
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()
这是一个有效的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)
速度大致相同,但在使用
广播时更灵活一些。为什么不使用列表压缩?我认为广播/缩小某些轴时会很复杂,但也许numpy通过使用某种迭代器支持这一点?我认为einsum是最糟糕的,因为我可能需要自己解析下标字符串。我没有使用过symarray
,但它看起来像对待任何其他对象数据类型数组一样。这意味着一些数学直接起作用,例如a+1
——无需lambdify
。但是将“函数”应用于a
(例如Max
)的每个元素需要显式迭代。请参阅我的编辑。另请参阅我所了解的np.max
是np.max.reduce
的缩写,就像np.sum
是np.add.reduce
的缩写一样。我可以按照hpaulj的建议,通过使用Pyfunc的来以元素方式在对象数组上应用np.max
或np.add
。另一方面,我发现很难应用像reduce
这样的广义函数。
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)