【问题标题】:Why a numpy array is still a <class 'numpy.ndarray'> when it has a "sympy.core.symbol.Symbol" inside?为什么当一个 numpy 数组里面有一个“sympy.core.symbol.Symbol”时,它仍然是一个 <class 'numpy.ndarray'>?
【发布时间】:2020-11-30 07:28:52
【问题描述】:

当我声明一个符号和这样的数组时

t  = symbols('t')
v1 = np.array([[1, 2, 3, 4, 5, ]])

print( type(v1) )

我在数组中放了一个符号

v2 = v1.dot(t)

print( type(v2) )

问题 1:为什么 v2 现在里面有一个符号,它仍然是一个 numpy.ndarray?

当我尝试整合这个数组时,我做不到

# I1 = integrate( v2 , t ) # this cannot be integrate because...

# AttributeError: 'ImmutableDenseNDimArray' object has no attribute 'as_poly'

那么,我必须这样做

v3 = smp.Matrix( v2 )

I2 = integrate( v3 , t )

问题 2:

是否有另一种方法可以集成 v2,而无需在 sympy Matrix 中对其进行更改?

【问题讨论】:

    标签: python arrays numpy types sympy


    【解决方案1】:

    sympynumpy 未集成。 sympy 对象在数组中工作,以至于它们可以被视为“对象”,并具有适当的方法。否则 numpy 不会对 sympy 对象做任何特别的事情。

    isympy 会话中:

    In [200]: t                                                                                          
    Out[200]: t
    
    In [201]: tau                                                                                        
    Out[201]: τ
    

    带有符号的数组将是object dtype。这就像一个列表,引用了这些数字和对象。这不是一个特殊的数组 dtype:

    In [202]: arr = np.array([1,2,tau,t])                                                                
    
    In [203]: arr                                                                                        
    Out[203]: array([1, 2, tau, t], dtype=object)
    

    np.dot 有效,因为符号可以相加和相乘:

    In [204]: np.dot(arr,arr)                                                                            
    Out[204]: 
     2    2    
    t  + τ  + 5
    
    In [205]: type(_)                                                                                    
    Out[205]: sympy.core.add.Add
    

    dot 与两个匹配的一维数组返回一个“标量”,在本例中为 sympy 对象。

    对于具有匹配大小的数字列表的点也是如此:

    In [206]: np.dot([1,2,3,4],arr)                                                                      
    Out[206]: 4⋅t + 3⋅τ + 5
    
    In [207]: type(_)                                                                                    
    Out[207]: sympy.core.add.Add
    

    但是带有标量 tau 的 3 元素列表中的点会生成一个数组:

    In [208]: np.array([1,2,3]).dot(tau)                                                                 
    Out[208]: array([tau, 2*tau, 3*tau], dtype=object)
    

    (3,4) 与 (4,) 的点产生一个 (3,) 数组:

    In [210]: np.ones((3,4),int).dot(arr)                                                                
    Out[210]: array([t + tau + 3, t + tau + 3, t + tau + 3], dtype=object)
    

    sympy 也不“知道”numpy,因此integrate(ndarray, ...) 不起作用也就不足为奇了。

    错误# AttributeError: 'ImmutableDenseNDimArray' object has no attribute 'as_poly' 表示数组已转换为ImmutableDenseNDimArray sympy 对象。无需详细说明,这显然是用于此目的的错误类型的 sympy 对象。

    与您的v2

    In [220]: v2                                                                                         
    Out[220]: array([[t, 2*t, 3*t, 4*t, 5*t]], dtype=object)
        
    In [222]: Matrix(v2)                                                                                 
    Out[222]: [t  2⋅t  3⋅t  4⋅t  5⋅t]
    
    In [225]: type(_222)                                                                                 
    Out[225]: sympy.matrices.dense.MutableDenseMatrix
    
    In [227]: ImmutableDenseNDimArray(v2)                                                                
    Out[227]: [[t  2⋅t  3⋅t  4⋅t  5⋅t]]
    
    In [228]: type(_)                                                                                    
    Out[228]: sympy.tensor.array.dense_ndim_array.ImmutableDenseNDimArray
    

    它们都没有as_poly 方法,但integrate 可能正在做一些进一步的处理。 numpy 有一个主类ndarray,它具有一组众所周知的方法和属性。 sympy 定义了更多的类,所以我们(我)需要更多地关注文档。这两个类(type(...).__mro__)的类层次结构完全不同。


    使用 Matrix 集成运行并生成:

    In [235]: integrate(Matrix(v2),t)                                                                    
    Out[235]: 
    ⎡ 2         2           2⎤
    ⎢t    2  3⋅t      2  5⋅t ⎥
    ⎢──  t   ────  2⋅t   ────⎥
    ⎣2        2           2  ⎦
    

    如果你提供了这个输出,那就太好了(礼貌!)。

    对于不起作用的情况,完整的回溯可能具有指导意义:

    In [236]: integrate(ImmutableDenseNDimArray(v2),t)                                                   
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-236-fbba47abf5a1> in <module>
    ----> 1 integrate(ImmutableDenseNDimArray(v2),t)
    
    /usr/local/lib/python3.6/dist-packages/sympy/integrals/integrals.py in integrate(*args, **kwargs)
       1543 
       1544     if isinstance(integral, Integral):
    -> 1545         return integral.doit(**doit_flags)
       1546     else:
       1547         new_args = [a.doit(**doit_flags) if isinstance(a, Integral) else a
    
    /usr/local/lib/python3.6/dist-packages/sympy/integrals/integrals.py in doit(self, **hints)
        592                 else:
        593                     antideriv = self._eval_integral(
    --> 594                         function, xab[0], **eval_kwargs)
        595                     if antideriv is None and meijerg is True:
        596                         ret = try_meijerg(function, xab)
    
    /usr/local/lib/python3.6/dist-packages/sympy/integrals/integrals.py in _eval_integral(self, f, x, meijerg, risch, manual, heurisch, conds)
        921 
        922         # try to convert to poly(x) and then integrate if successful (fast)
    --> 923         poly = f.as_poly(x)
        924         if poly is not None and not (manual or meijerg or risch):
        925             return poly.integrate().as_expr()
    
    AttributeError: 'ImmutableDenseNDimArray' object has no attribute 'as_poly'
    

    我们需要深入研究这段代码(即 922 行)以找出它为何尝试 f.as_poly。它也尝试过Matrix,还是采取了不同的路线? sympy 这样的代码中发生了很多事情!


    一开始你不需要使用np.array。坚持sympy

    In [249]: integrate(Matrix([[1,2,3,4,5]])*t,t)                                                       
    Out[249]: 
    ⎡ 2         2           2⎤
    ⎢t    2  3⋅t      2  5⋅t ⎥
    ⎢──  t   ────  2⋅t   ────⎥
    ⎣2        2           2  ⎦
    

    【讨论】:

    • 感谢您的回答。问题是我正在从 Matlab 转向 python,并且我习惯于使用数组(只有一种类型)来完成我的所有代码,而无需照顾此类问题。
    • 那么我问你,进行这种转变是个好主意吗?
    • MATLAB 在我几年前使用它时并没有符号的东西(我为此使用了 MAPLE 和 MacSyma),但在 MATLAB 中矩阵(2d 及以上)是核心结构。 sympy 是基于 python 构建的,而不是 numpy。 Octave 的符号包(免费 MATLAB)基于sympy,所以这可能是一个更好的桥梁。但我不知道细节。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    • 1970-01-01
    • 2022-08-16
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多