了解 numpy "void" dtype 和泛型数组

Understanding numpy "void" dtype and generic arrays

我正在尝试创建一个包含 2 个元素元组的 numpy 数组,其中第一个可以是任何元素,第二个是整数。阅读 numpy 文档我发现 numpy.void 类型是一种通用类型。如果我将我的新类型定义为:

In [1]: import numpy as np
In [2]: dt = np.dtype([('anything', 'V', 1), ('counter', 'i4', 1)])

我能做到:

In [3]: np.array([("hi", 1), ("bye", 1)], dtype=dt)
Out[3]: 
array([(<read-write buffer ptr 0x12f9bb0, size 1 at 0x7f03d020f870>, 1),
   (<read-write buffer ptr 0x12f9bb5, size 1 at 0x7f03d020f830>, 1)], 
  dtype=[('anything', 'V1'), ('counter', '<i4')])

但是我做不到:

In [4]: np.array([(1, 1), (2, 1)], dtype=dt)
------------------------------------------------------------
TypeError                  Traceback (most recent call last)
<ipython-input-4-637fcc25185b> in <module>()
----> 1 np.array([(1, 1), (2, 1)], dtype=dt)

TypeError: expected a readable buffer object

有没有一种方法可以使用 numpy dtypes 生成通用元组?

Dtype O(对象)可能比V更通用。然后数组将在指针点处有 space - 它可以指向任何类型的 Python 对象,无论是字符串、数字、列表、元组还是自定义 class .

In [85]: dt=np.dtype([('anything', 'O'), ('counter','i4')])

In [86]: np.array([("hi",1), ("bye",1), ((1,1),2), (3,4)],dtype=dt)
Out[86]: 
array([('hi', 1), ('bye', 1), ((1, 1), 2), (3, 4)], 
      dtype=[('anything', 'O'), ('counter', '<i4')])

我认为你的规范中的 V1 是一个没有意义的字节,你的第一个案例描述为 <read-write buffer ptr 0x12f9bb0, size 1 at 0x7f03d020f870>


这是一种足够大的 void 可以用作序列化缓冲区的方法

In [119]: dt1=np.dtype([('anything', 'V',10), ('counter','i4')])
In [120]: A1=np.zeros(5,dt1)

In [121]: A1['anything'][0]=b'anything'
In [122]: A1['anything'][1]=b'0123456789'


In [123]: A1['anything'][2]=pickle.dumps((1,2)) 
In [124]: pickle.loads(A1['anything'][2])
Out[124]: (1, 2)

我将一个字段定义为 V10 缓冲区。我可以将不超过该长度的任何字节字符串分配给该字段的各个元素,包括 pickle.dumps.

的输出
In [128]: pickle.dumps((1,2))
Out[128]: b'\x80\x03K\x01K\x02\x86q\x00.'

尝试 pickle (1,2,3) 不起作用 - 我可以进行分配,但加载失败,因为整个缓冲区不适合。

In [156]: A1
Out[156]: 
array([([97, 110, 121, 116, 104, 105, 110, 103, 0, 0], 0),
       ([48, 49, 50, 51, 52, 53, 54, 55, 56, 57], 0),
       ([-128, 3, 75, 1, 75, 2, -122, 113, 0, 46], 0),
       ([-128, 3, 71, 64, 40, -103, -103, -103, -103, -103], 0),
       ([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0)], 
      dtype=[('anything', 'V10'), ('counter', '<i4')])

所以我们必须深入研究一下如何 return 我最初定义的字节字符串。数字也必须以一种或其他方式序列化。我们总是可以求助于 pickle 的一切。 JSON 是另一个序列化选项。