我有一个巨大的二进制文件(几个GB)具有以下DATAFORMAT:快速阅读和解释二进制文件
4个后续字节构成一个复合数据点(32位),其由以下组成:
b0-b3 4 flag bits
b4-b17 14 bit signed integer
b18-b32 14 bit signed integer
我需要分别访问带符号整数和标志位,并附加到列表或一些更智能的数据结构(尚未决定)。目前我使用下面的代码来阅读:
from collections import namedtuple
DataPackage = namedtuple('DataPackage', ['ie', 'if1', 'if2', 'if3', 'quad2', 'quad1'])
def _unpack_integer(bits):
value = int(bits, 2)
if bits[0] == '1':
value -= (1 << len(bits))
return value
def unpack(data):
bits = ''.join(['{0:08b}'.format(b) for b in bytearray(data)])
flags = [bool(bits[i]) for i in range(4)]
quad2 = _unpack_integer(bits[4:18])
quad1 = _unpack_integer(bits[18:])
return DataPackage(flags[0], flags[1], flags[2], flags[3], quad2, quad1)
def read_file(filename, datapoints=None):
data = []
i = 0
with open(filename, 'rb') as fh:
value = fh.read(4)
while value:
dp = unpack(value)
data.append(dp)
value = fh.read(4)
i += 1
if i % 10000 == 0:
print('Read: %d kB' % (float(i) * 4.0/1000.0))
if datapoints:
if i == datapoints:
break
return data
if __name__ == '__main__':
data = read_heterodyne_file('test.dat')
此代码的工作,但它是我的目的,(2秒为10万个数据点与4字节每个)太慢。至少我需要10倍的速度。
分析器说,代码花费的时间大部分是字符串格式(获取位)和_unpack_integer()。
不幸的是我不知道如何在这里继续。我正在考虑使用cython或直接编写一些c代码来完成读取。我也尝试过Pypy ant,它给了我巨大的性能提升,但不幸的是,它需要兼容一个更大的项目,它不能与Pypy一起工作。
删除格式并直接在读取值上使用掩码。跳过“转换为字符串以获取位”阶段。 –
谢谢。这似乎很有道理。所以得到quad2我需要沿着行数据= 00001111111111111100000000000000,然后我不知道如何将其转换为int16 – dreichler
为了严格起见,1 kB有** 1024 ** B(不是1000)。 – CristiFati