我有一個巨大的二進制文件(幾個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