在Python 3中将字节数组转换为浮点数组 使用结构使用数组

问题描述

我正在从C程序向STDOUT发送二进制形式的1.0和2.0:

    float array[2] = { 1.0,2.0 };
    fwrite(&array[0],sizeof(array[0]),sizeof(array) / sizeof(array[0]),stdout);
    fflush(stdout);

Python程序将STDOUT读取为:

b'\x00\x00\x80?\x00\x00\x00@'

当我尝试将其转换回浮点型时,这可行:

struct.unpack('<f',array[0:4]) # 1.0
struct.unpack('<f',array[4:8]) # 2.0

但是,如果我尝试一次解码整个数组,它将失败:

struct.unpack('<f',array)

显示以下消息:

error: unpack requires a buffer of 4 bytes

是否可以一次解码整个数组,还是应该在循环中分别解码每个浮点数?

解决方法

使用结构

基于struct module documentationstruct.unpack()函数必须具有定义的准确格式,才能一次解压缩多个值。因此,如果需要使用struct模块,则必须使用'<ff'格式定义格式,或者使用struct.iter_unpack(format,buffer)遍历数组。

使用数组

另一种选择是使用array模块,该模块允许您立即解码二进制数据。您可以使用array.byteswap()方法更改字节序。唯一的限制是整个数组必须具有相同的类型。

import array

arr = array.array('f',b'\x00\x00\x80?\x00\x00\x00@')

arr.tolist()
# [1.0,2.0]

# change endianness
arr.byteswap()

arr.tolist()
# [4.600602988224807e-41,8.96831017167883e-44]
,

Python的strcut提供了一些必要的工具,但是使用起来有些笨拙。 特别是为此,它必须将所有浮点数生成为Python浮点数的元组(每个都是10字节的“巨大” objetcs),然后将其插入到数组中。

幸运的是,Python的array.array类本身可以在给定byte对象的情况下填充其值,甚至可以直接从文件中读取该值。


import array

data = b'\x00\x00\x80?\x00\x00\x00@'
arr = array.array('f')
arr.frombytes(data)
print(arr)

收益:

array('f',[1.0,2.0])

(要直接从文件中读取,请使用fromfile方法)