【问题标题】:Accessing contents of numpy.ndarray fields访问 numpy.ndarray 字段的内容
【发布时间】:2021-03-26 00:15:16
【问题描述】:

我从 python 中的 sympy lambdify 函数创建了一个 ndarray,我需要的实际值隐藏在我的结果变量的这个数组字段中。需要明确的是,array 沿 axis=0 的每个索引对应于特定时刻的 7 阶时间多项式的一阶导数:

在我的 lambdify 函数中,我传递了一个大小为 33 的元素时间向量,并期望得到 8x33 或 33x8 的结果,但它却将我的输出推送到了这个数组字段,我无法访问它。现在,我只能通过result[0]result[1] 等来访问它,但这很乏味,因为我一次只能访问所有内容,这意味着循环是访问所有内容的唯一方法。这不是我期望的 ndarray 的行为:

谁能解释这里发生了什么,如果可能的话,我如何访问这个数组字段,以便我可以向量化任何后续操作?我的目标是沿axis=0堆叠数组中的每个元素并计算后续导数并根据它们各自的时间堆叠它们。

【问题讨论】:

  • lambdify 是 sympy 的东西,而不是 numpy,所以你还需要标记这个sympy

标签: python numpy sympy numpy-ndarray lambdify


【解决方案1】:

lambdified 函数的doc 显示实际上是numpy 代码。有时看看这个会有所帮助。

破译您的png 需要一些时间(我们通常不喜欢 SO 上的那些)。我猜这是result 数组的pydev 显示。它看起来像一个形状 (8,) 对象 dtype 数组。大部分元素是 shape(33,) 数组,但最后 2 个是标量。

np.stack(result[:6])

应该产生一个 (8,33) 数字 dtype 数组。

对象 dtype 数组很像一个列表,其中包含对不同元素的引用。

看看你的多项式,我猜lambdified函数返回如下内容:

np.array([7*t**6, ..., 2*t, 1, 0])

虽然其中 6 个术语包含 t,但最后 2 个不包含。包含t 的术语将生成一个 (33,) 数组。 sympy.lambdify 是一个相对简单的函数,执行从sympynumpy 的词法转换。它对numpy没有“深入”的了解。


例子:

In [25]: exp = (3*t**3,2*t**2,1*t,1.0,0)
In [26]: f = lambdify(t, exp)
In [27]: print(f.__doc__)
Created with lambdify. Signature:

func(t)

Expression:

(3*t**3, 2*t**2, t, 1.0, 0)

Source code:

def _lambdifygenerated(t):
    return ((3*t**3, 2*t**2, t, 1.0, 0))

In [28]: f(np.arange(3))
Out[28]: (array([ 0,  3, 24]), array([0, 2, 8]), array([0, 1, 2]), 1.0, 0)
In [29]: np.array(_)
<ipython-input-29-7a2cd91c32ca>:1: 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.
  np.array(_)
Out[29]: 
array([array([ 0,  3, 24]), array([0, 2, 8]), array([0, 1, 2]), 1.0, 0],
      dtype=object)

【讨论】:

  • 请注意,在我的测试中,np.stack(result[:6]) 不会生成 8x33 数组,而是生成 6x33 数组,这有点问题,比其他任何东西都更烦人。这意味着我必须手动重复它们并将它们添加回适当的尺寸。如果对于不依赖于 t 的术语,lambdify 将返回适当的维度而不是将它们截断为大小 1,那就太好了。没有任何意义。
  • 你必须比lambdify更聪明。就像我说的,它基本上是一个词汇翻译。在您的多项式中,1.0 是一个标量,没有任何东西可以转换为np.ones_like(t)。当人们使用sympy.Matrix 时,我已经看到了同样的问题。至少在理论上,你比lambdify 知道的更多numpy
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-02
  • 1970-01-01
  • 2013-04-17
  • 2019-11-18
  • 1970-01-01
  • 2017-03-26
相关资源
最近更新 更多