NumPy数组自定义dtype转换报错:缓冲区大小需为元素整数倍
问题描述
有如下numpy数组参数:
param_get_indirect = np.array([[1.1304908, 1.0647957, 1., 0.97220206, 0.9649332, 0.8939871, 0.81870604, 0.73949486,0.73949486, 0.73949486]],dtype='float32')
尝试将其转换为自定义dtype时失败,使用getsizeof(param_get_indirect.tobytes())获取字节大小后,定义了如下dtype:
response_dtype = np.dtype([('a', 'u4'), ('b', 'u4'), ('c', 'u1', num - 8)])
执行转换代码:
response_tlv_array = np.array(np.frombuffer(param_get_indirect,dtype=np.dtype(response_dtype)))
触发报错:
ValueError: buffer size must be a multiple of element size
尽管打印response_dtype.itemsize和getsizeof(param_get_indirect.tobytes())的结果均为73,问题仍未解决。完整代码如下:
param_get_indirect = np.array([[1.1304908, 1.0647957, 1., 0.97220206, 0.9649332, 0.8939871, 0.81870604, 0.73949486, 0.73949486, 0.73949486]], dtype='float32') num = getsizeof(param_get_indirect.tobytes()) print(getsizeof(param_get_indirect.tobytes())) response_dtype = np.dtype([('a', 'u4'), ('b', 'u4'), ('c', 'u1', num - 8)]) print(response_dtype.itemsize) response_tlv_array = np.array(np.frombuffer(param_get_indirect,dtype=np.dtype(response_dtype)))
问题原因与解决方法
错误根源
getsizeof()返回的是Python对象的总内存占用,包含了bytes对象本身的管理开销,并非数组原始数据的真实字节长度。你拿到的73是bytes对象的总大小,而数组实际的原始数据长度是40(10个float32元素,每个占4字节:10*4=40)。
修正步骤
直接使用numpy数组的nbytes属性获取数据的真实字节长度,这个属性仅计算数组本身的存储大小,不含额外对象开销。
修正后的完整代码:
import numpy as np from sys import getsizeof param_get_indirect = np.array([[1.1304908, 1.0647957, 1., 0.97220206, 0.9649332, 0.8939871, 0.81870604, 0.73949486, 0.73949486, 0.73949486]], dtype='float32') # 用nbytes获取数组真实字节长度,替代getsizeof处理tobytes() num = param_get_indirect.nbytes print(f"数组真实字节长度: {num}") # 输出40 # 定义自定义dtype,确保总大小与数组字节长度匹配 response_dtype = np.dtype([('a', 'u4'), ('b', 'u4'), ('c', 'u1', num - 8)]) print(f"自定义dtype的itemsize: {response_dtype.itemsize}") # 输出40 # np.frombuffer直接返回ndarray,无需再用np.array包裹 response_tlv_array = np.frombuffer(param_get_indirect.tobytes(), dtype=response_dtype) print(response_tlv_array)
额外注意点
np.frombuffer返回的已经是numpy数组,不需要再嵌套np.array(),否则会生成一个包含单个数组元素的二维数组。- 自定义dtype的
itemsize必须和输入字节流的长度完全一致,这样才能保证缓冲区大小是元素大小的整数倍(这里刚好是1倍),避免报错。
内容的提问来源于stack exchange,提问作者Ino
相关产品推荐
相关产品推荐

