我可以使用myndarray.tobytes()
将numpy ndarray转换为字节现在我怎样才能将它恢复为ndarray?
使用.tobytes()
方法docs:
>>> 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 :(得分:3)
编辑后,你似乎走错了方向!
当仅需要从这些字节进行重建时,您无法使用 np.tobytes()
来存储包含形状和类型等所有信息的完整数组!它只会保存原始数据(单元格值)并在C或Fortran顺序中展平它们。
现在我们不知道你的任务。但是你需要基于序列化的东西。有很多方法,最简单的是基于python的pickle(例如: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)
输出:
[[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]]
更好的选择是joblib's pickle,对大型阵列进行专门的酸洗。 joblib的函数是基于文件对象的,并且可以使用python&#39; s BytesIO在内存中使用字节字符串。
答案 1 :(得分:2)
要反序列化字节,您需要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..."
答案 2 :(得分:0)
如果您提前知道要重新创建的维度,请执行
numpy.ndarray(<dimensions>,<dataType>,<bytes(aka buffer)>)
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)
#array([[1. , 1.1, 1.2, 1.3],
# [2. , 2.1, 2.2, 2.3],
# [3. , 3.1, 3.2, 3.3]])
xBytes = x.tobytes()
#b'\x00\x00\x00\x00\x00\x00\xf0?\x9a\x99\x99\x99\x99\x99\xf1?333333\xf3?\xcd\xcc\xcc\xcc\xcc\xcc\xf4?\x00\x00\x00\x00\x00\x00\x00@\xcd\xcc\xcc\xcc\xcc\xcc\x00@\x9a\x99\x99\x99\x99\x99\x01@ffffff\x02@\x00\x00\x00\x00\x00\x00\x08@\xcd\xcc\xcc\xcc\xcc\xcc\x08@\x9a\x99\x99\x99\x99\x99\t@ffffff\n@'
newX = numpy.ndarray((3,4),numpy.float64,xBytes)
#array([[1. , 1.1, 1.2, 1.3],
# [2. , 2.1, 2.2, 2.3],
# [3. , 3.1, 3.2, 3.3]])
另一种方法可能是,如果您将数据存储为字节记录而不是整个 ndarray,并且您选择的数据从 ndarray 到 ndarray 不同,您可以将预数组数据聚合为 python 字节数组中的字节,那么当它是所需的大小时,您已经知道所需的维度,并且可以将字节数组作为缓冲区提供这些维度/数据类型。