使用Python从二进制文件中读取32位带符号的IEEE 754浮点数?

25

我有一个二进制文件,它只是由有符号32位IEEE754浮点数列表组成。它们没有被任何东西分隔,而是一个接一个地出现,直到EOF。

我该如何从此文件中读取并正确解释它们为浮点数呢?

我尝试使用read(4),但它会自动将它们转换为带ASCII编码的字符串。

我还尝试使用bytearray,但它只按1个字节一次读取,而不是我需要的4个字节。

4个回答

34
struct.unpack('f', file.read(4))

您也可以同时解压缩多个文件,这样速度会更快:

struct.unpack('f'*n, file.read(4*n))

1
“+1 for the 'f'*n;”这个语法在哪里有文档记录?我在学习Python的时候可能错过了。 - Andrew White
3
字符串的乘法在教程和序列对象的库参考部分中有文档记录。 - Thomas Wouters
4
更一般的拆包多个值的方法是unpack('{0}f'.format(n), ...),或者如果您预先知道数量,只需使用unpack('10f', ...)。 最好使用内置的重复方法,而不是依赖字符串操作。 - Scott Griffiths
2
@cdiggins:我倾向于选择需要最少打字和最容易阅读的选项。这两个因素有时会发生冲突,所以您可能需要在它们之间进行权衡,但在这种情况下,我的版本既更短又更清晰。就性能而言,我预计这两种形式几乎相同,因为大部分时间都花在了I/O子系统上。如果长度在编码时已知,则我同意'10f'更好,原因完全相同:它比'f'*10稍微更短且更易于阅读。 - Marcelo Cantos
5
@Marcelo,我同意这个原则,但是考虑到解包100,000个整数。对我来说创建一个长度为100k的格式字符串没有意义。相反,使用'{0}f'.format(1000000)更合理。 - cdiggins
显示剩余2条评论

5

请查看struct.unpack。类似以下的代码可能会起作用...

f = struct.unpack('f', data_read)

3
import struct
(num,) = struct.unpack('f', f.read(4))

0

到目前为止,我发现最快的方法(就性能而言)是 numpy.fromfile

import numpy as np

class FloatReader:
    def __init__(self, filename):
        self.f = open(filename, "rb")
    
    def read_floats(self, count : int):
        return np.fromfile(self.f, dtype=np.float32, count=count, sep='')

这种方法在性能方面比struct.unpack快得多!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接