如何从字节创建一个numpy的ndarray?

17 浏览
0 Comments

如何从字节创建一个numpy的ndarray?

我可以使用myndarray.tobytes()将numpy的ndarray转换为字节。那么如何将其转换回ndarray呢?

使用.tobytes()方法文档中的示例:

>>> x = np.array([[0, 1], [2, 3]])
>>> bytes = x.tobytes()
>>> bytes
b'\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'
>>> np.some_magic_function_here(bytes)
array([[0, 1], [2, 3]])

0
0 Comments

问题的出现原因是用户想要将字节数据转换为numpy的ndarray对象。解决方法有两种。

第一种方法是如果用户在转换之前已经知道了ndarray对象的维度,可以使用以下代码进行转换:

import numpy
x = numpy.array([[1.0,1.1,1.2,1.3],[2.0,2.1,2.2,2.3],[3.0,3.1,3.2,3.3]],numpy.float64)
xBytes = x.tobytes()
newX = numpy.ndarray((3,4),numpy.float64,xBytes)

第二种方法是如果用户的数据以字节记录的形式存储,而不是作为整个ndarray对象,并且每个ndarray对象的选择的数据都不同,可以将预先准备好的数据作为字节存储在python的bytearray中,然后在达到所需的大小时,以bytearray作为缓冲区提供所需的维度和数据类型。

以上就是问题的原因和解决方法。

0
0 Comments

如何从字节创建一个numpy ndarray?

要反序列化字节,您需要使用np.frombuffer()函数。tobytes()函数将数组序列化为字节,而np.frombuffer()函数将其反序列化。请注意,一旦序列化,形状信息就会丢失,这意味着在反序列化之后,需要将其重新reshape回原始形状。

下面是一个完整的示例:

import numpy as np
x = np.array([[0, 1], [2, 3]], np.int8)
bytes = x.tobytes()
# bytes 是一个原始数组,不包含有关 x 形状的信息
# 让我们确保:我们有4个值,数据类型为 int8(每个数组项占用一个字节),因此 bytes 的长度应为 4 个字节
assert len(bytes) == 4, "Ha??? Weird machine..."
deserialized_bytes = np.frombuffer(bytes, dtype=np.int8)
deserialized_x = np.reshape(deserialized_bytes, newshape=(2, 2))
assert np.array_equal(x, deserialized_x), "Deserialization failed..."

以上是解决该问题的方法。通过使用np.frombuffer()函数从字节中反序列化数组,并使用np.reshape()函数将其恢复到原始形状,可以实现从字节创建numpy ndarray的目的。

0
0 Comments

如何从字节中创建一个numpy ndarray?

在编辑之后,看起来你走错了方向!当只需要从这些字节中重建数组时,你不能使用np.tobytes()来存储包含所有信息(如形状和类型)的完整数组!它只会保存原始数据(单元格值)并按照C或Fortran顺序展开这些数据。

现在我们不知道你的任务是什么。但是你将需要基于序列化的方法。有很多方法可以实现,其中最简单的是使用Python的pickle(以下是一个示例,适用于Python 3):

import pickle
import numpy as np
x = np.array([[0, 1], [2, 3]])
print(x)
x_as_bytes = pickle.dumps(x)
print(x_as_bytes)
print(type(x_as_bytes))
y = pickle.loads(x_as_bytes)
print(y)

输出结果:

[[0 1]
 [2 3]]
b'\x80\x03cnumpy.core.multiarray\n_reconstruct\nq\x00cnumpy\nndarray\nq\x01K\x00\x85q\x02C\x01bq\x03\x87q\x04Rq\x05(K\x01K\x02K\x02\x86q\x06cnumpy\ndtype\nq\x07X\x02\x00\x00\x00i8q\x08K\x00K\x01\x87q\tRq\n(K\x03X\x01\x00\x00\x00<q\x0bNNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00tq\x0cb\x89C \x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00q\rtq\x0eb.'

[[0 1]
 [2 3]]

更好的选择是joblib的pickle,它对大型数组进行了专门的拾取。joblib的函数基于文件对象,也可以使用字节字符串在内存中使用,使用Python的BytesIO。

参考链接:

- [joblib](https://pythonhosted.org/joblib/)

- [BytesIO](https://docs.python.org/3/library/io.html#binary-i-o)

0