【问题标题】:Instantiate scalar of custom structured dtype实例化自定义结构化 dtype 的标量
【发布时间】:2020-12-30 11:48:52
【问题描述】:

我已经定义了一个自定义 dtype。例如:

vec = np.dtype([('x', float), ('y', float), ('z', float)])
quat = np.dtype([('w', float), ('v', vec)])

现在我想做一个标量四元数:

quat((1.0, (0.0, 0.0, 0.0)))

我希望如果有的话,我的元组语法是不可接受的。但是,相反,我收到以下错误:

TypeError: 'numpy.dtype' object is not callable

documentation on scalars 中的 relevant portion 意味着可以在 numpy 中构建这样的结构化类型的标量。

如何实例化quat 标量?有可能吗?

顺便说一句,我使用了以下解决方法:

np.array([(1.0, (0.0, 0.0, 0.0))], dtype=quat)

这不会产生实际的标量(尽管老实说它对于我的目的来说已经足够好了,这使得这个问题主要是理论上的)。对结果调用 item 会返回 tuple,而不是标量 quat 对象。

【问题讨论】:

  • 虽然intnp.float32 可以同时作为dtype 和函数来创建一个numpy 标量,但我不认为np.dtype 实例可以做到这一点。它没有__call__ 方法(检查一下)。
  • 复合数据类型创建一个np.void 对象。 (或recarraynp.record
  • @hpaulj。我完全同意。但是文档中似乎隐含了 some 方式。我想如果有人知道,那就是你,Divakar 左右。
  • @hpaulj。所以我试着做quat.type(pack('dddd', 1.0, 0.0, 0.0, 0.0))。这可能是朝着正确方向迈出的一步,但其原始形式并不完全有帮助
  • @hpaulj。明白了:quat.type(pack('dddd', 1.0, 0.0, 0.0, 0.0)).view(quat)

标签: python numpy scalar


【解决方案1】:

这是基于 cmets 中的讨论。这比它需要的更痛苦,因为自定义标量的用例不太可能使用 1 元素数组更方便地解决。

quat 的类型是np.void

>>> quat.type
numpy.void

由于这是自定义类型的通用包罗万象,因此必须使用类似字节的对象对其进行实例化:

>>> from struct import pack
>>> q = quat.type(pack('dddd', 1.0, 0.0, 0.0, 0.0))
>>> q
void(b'\x00\x00\x00\x00\x00\x00\xF0\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')

当然,既然它是一个通用的包罗万象,你需要告诉它如何解释自己。幸运的是,标量也有一个view 方法:

>>> q = q.view(quat)
>>> q
(1., (0., 0., 0.))
>>> q.dtype
dtype([('w', '<f8'), ('v', [('x', '<f8'), ('y', '<f8'), ('z', '<f8')])])

TL;DR

q = np.void(pack('dddd', 1.0, 0.0, 0.0, 0.0)).view(quat)

【讨论】:

    【解决方案2】:

    在您的数组上调用 item 会生成一个元组,因为 item 专门用于将 NumPy 类型转换为 Python 类型。对数组进行索引会生成 numpy.void 类型的 NumPy 标量:

    scalar = np.array([(1.0, (0.0, 0.0, 0.0))], dtype=quat)[0]
    

    【讨论】:

    • 这确实比我的版本干净得多。谢谢。
    猜你喜欢
    • 2013-09-04
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多