ndarray tobytes() 是否创建原始数据的副本?

Does ndarray tobytes() create a copy of raw data?

我写了一些代码

batch = np.ones([4, 3, 224, 224], dtype="float32")
import time
s = time.time()
batch_bytes = batch.tobytes()
e = time.time()
print(f"{(e-s)*1e3} ms")

这给出了 2.2954940795898438 ms

的输出

好像开销不小,我猜这个方法会复制数据字节?

以前一直以为数据在内存中是按字节存储的,所以有直接获取的方法吗?

那么有没有可能更有效地获取字节?

是的,ndarray.tobytes() 会创建数据副本并将其存储在计算机内存中的不同位置。 NumPy 的文档 https://numpy.org/doc/stable/reference/generated/numpy.ndarray.tobytes.html

中也对此进行了描述

您可以通过打印对象的内存地址轻松地对此进行测试。

import numpy as np
import time

batch = np.ones([4, 3, 224, 224], dtype="float32")
s = time.time()
batch_bytes = batch.tobytes()
e = time.time()
print(f"{(e-s)*1e3} ms")

print(f"Batch object address:       {hex(id(batch))}")
print(f"batch_bytes object address: {hex(id(batch_bytes))}")

给出输出:

Batch object address:       0x7f16beab0990
batch_bytes object address: 0x7f16be491010

是的,它制作了一个副本,因为 bytes 类型必须拥有其原始数据的 所有权 (即,副本是强制性的)。但是,您可以使用以下方法创建 Numpy 数组的 view 而无需任何副本:

batch_bytes = batch.reshape(-1).view(np.uint8)

请注意,结果类型不同(一维 Numpy 数组)。

此处发布了相同的问题:

要从 array:ndarray 获取字节,使用 array.data 将获取字节的内存视图(参考)