我可以使用以下方法将numpy ndarray转换为字节:myndarray.tobytes()如何将其返回到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]])
Run Code Online (Sandbox Code Playgroud)
编辑后,您似乎走错了方向!
np.tobytes() 当仅需要从这些字节进行重构时,您不能用于存储包含所有信息(如形状和类型)的完整数组!它只会保存原始数据(单元格值)并以 C 或 Fortran 顺序将它们展平。
现在我们不知道你的任务。但是你需要一些基于序列化的东西。有很多方法,最简单的方法是以下基于 python 的泡菜(例如:python3!):
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)
Run Code Online (Sandbox Code Playgroud)
输出:
[[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.'
<class 'bytes'>
[[0 1]
[2 3]]
Run Code Online (Sandbox Code Playgroud)
更好的选择是joblib 的pickle,它为大型数组提供专门的pickle。joblib 的函数是基于文件对象的,也可以使用 python 的BytesIO在内存中使用字节字符串。
要反序列化所需的字节np.frombuffer()。
tobytes()将数组序列化为字节,然后np.frombuffer()反序列化它们。
请记住,序列化后,形状信息会丢失,这意味着在反序列化之后,需要将其重新成形为原始形状。
下面是一个完整的示例:
import numpy as np
x = np.array([[0, 1], [2, 3]], np.int8)
bytes = x.tobytes()
# bytes is a raw array, which means it contains no info regarding the shape of x
# let's make sure: we have 4 values with datatype=int8 (one byte per array's item), therefore the length of bytes should be 4bytes
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..."
Run Code Online (Sandbox Code Playgroud)