从具有不同数据类型的缓冲区读取numpy数组而不复制数组

时间:2018-02-21 00:08:40

标签: python numpy

我将数据编码为二进制字符串,混合使用数据类型。

作为一个例子(实际数据要大得多),

data = b'l:\x00\x00\xc0\xff|:g\x8em\xbf}:\xceUq\xbf'

我正在把它读成一个numpy数组:

buffer = np.frombuffer(np.array(data), dtype='B')

给出了

array([108,  58,   0,   0, 192, 255, 124,  58, 103, 142, 109, 191, 125,
    58, 206,  85, 113, 191], dtype=uint8)

我需要将其更改为(np.uint16, np.float),因此上面的数组是

[(14956,NaN),(14972,-0.9280),(14973,-0.9427)]

我可以将视图用于单个数据类型,例如     buffer.view(dtype=np.uint16)给出了

array([14956,     0, 65472, 14972, 36455, 49005, 14973, 21966, 49009], dtype=uint16)

但是,我认为我不能像这样使用数据类型的组合。我尝试过重塑和切片,

buffer = buffer.reshape((3,-1))
firstData = buffer[:,:2]
firstData = array([[108,  58],
                   [124,  58],
                   [125,  58]], dtype=uint8)
firstData.view(dtype = np.uint16)
ValueError: new type not compatible with array.

正如文档中所暗示,这可以通过复制来解决

firstData = firstData.copy()
firstData.view(dtype=np.uint16)
array([[14956],
       [14972],
       [14973]], dtype=uint16)

有没有快速的方法可以在不复制数组的情况下执行此操作?

1 个答案:

答案 0 :(得分:1)

使用包含两个字段的结构化数据类型:

In [89]: data = b'l:\x00\x00\xc0\xff|:g\x8em\xbf}:\xceUq\xbf'

In [90]: dt = np.dtype([('a', np.uint16), ('b', np.float32)])

In [91]: x = np.frombuffer(data, dtype=dt)

In [92]: x
Out[92]: 
array([(14956,         nan), (14972, -0.92795414), (14973, -0.94271553)], 
      dtype=[('a', '<u2'), ('b', '<f4')])

x是一维的structured array; x中的每个项目都是包含字段ab的结构:

In [93]: x[0]
Out[93]: (14956,  nan)

In [94]: x['a']
Out[94]: array([14956, 14972, 14973], dtype=uint16)

请注意,我使用np.float32作为浮点字段。 np.float是Python内置float的别名。如果将其用作数据类型,则numpy将其视为64位浮点数。