将字节数组转换回numpy数组

时间:2018-11-19 14:30:42

标签: python python-3.x numpy

您可以使用.tobytes()函数将numpy数组转换为字节。

如何将其从此字节数组解码回numpy数组? 我对形状为(28,28)的数组i进行了这样的尝试

>>k=i.tobytes()

>>np.frombuffer(k)==i

False

也尝试过使用uint8。

2 个答案:

答案 0 :(得分:8)

虽然您可以使用tobytes(),但这并不是理想的方法,因为它不存储numpy数组的形状信息。

如果必须将其发送到没有有关形状的信息的另一个过程,则必须显式发送形状信息。

一个更优雅的解决方案是使用np.save将其保存到BytesIO缓冲区,然后使用np.load进行恢复。这样,您就不需要在任何地方专门存储形状信息,并且可以轻松地从字节值中恢复numpy数组。

示例:

>>> import numpy as np
>>> from io import BytesIO

>>> x = np.arange(28*28).reshape(28, 28)
>>> x.shape
(28, 28)

# save in to BytesIo buffer 
>>> np_bytes = BytesIO()
>>> np.save(np_bytes, x, allow_pickle=True)

# get bytes value
>>> np_bytes = np_bytes.getvalue()
>>> type(np_bytes)
<class 'bytes'>

# load from bytes into numpy array
>>> load_bytes = BytesIO(np_bytes)
>>> loaded_np = np.load(load_bytes, allow_pickle=True)

# shape is preserved
>>> loaded_np.shape
(28, 28)

# both arrays are equal without sending shape
>>> np.array_equal(x,loaded_np)
True

答案 1 :(得分:5)

您正在做的事情有两个问题:

  1. frombuffer将始终将输入解释为一维数组。这是documentation的第一行。因此,您必须将其重塑为(28, 28)

  2. 默认dtypefloat。因此,如果您没有序列化浮点数,则必须手动指定dtype(先验的是没人能说出字节流的含义:您必须说出它们代表什么)。

  3. 如果要确保数组相等,则必须使用np.array_equal。使用==会进行元素操作,并返回numpy布尔数组(大概不是您想要的)。

  

如何将其从此字节数组解码回numpy数组?

示例:

In [3]: i = np.arange(28*28).reshape(28, 28)

In [4]: k = i.tobytes()

In [5]: y = np.frombuffer(k, dtype=i.dtype)

In [6]: y.shape
Out[6]: (784,)

In [7]: np.array_equal(y.reshape(28, 28), i)
Out[7]: True

HTH。