实例化自定义结构化数据类型的标量

Instantiate scalar of custom structured 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

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

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

顺便说一句,我试过以下解决方法:

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

这不会产生实际的标量(尽管老实说它对我的目的来说效果很好,使问题主要是理论上的)。对结果 returns 调用 item 一个 tuple,而不是标量 quat 对象。

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

quat的类型是np.void:

>>> quat.type
numpy.void

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

>>> 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')

当然,由于它是通用的 catch-all,您需要告诉它如何解释自己。幸运的是,标量也有一个 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)

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

的 NumPy 标量
scalar = np.array([(1.0, (0.0, 0.0, 0.0))], dtype=quat)[0]