理解numpy“void”dtype和泛型数组

时间:2015-01-15 23:01:44

标签: python arrays generics numpy

我试图创建一个包含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的通用元组的方法?

1 个答案:

答案 0 :(得分:1)

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

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

尝试挑选(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')])

所以我们必须仔细研究一下如何返回我最初定义的字节串。数字也必须以某种方式序列化。对于一切,我们总是可以依靠pickleJSON是另一个序列化选项。