解釈:速読、私は、次のデータフォーマットを有する巨大なバイナリファイル(数GB)を持つバイナリファイル
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')
このコードは動作しますが、それは私の目的(4バイトごとで100kのデータポイントのため2S)には遅すぎるのです。少なくとも10倍のスピードが必要です。
プロファイラでは、コードが文字列形式(ビットを取得する)と_unpack_integer()でほとんど時間を費やしていることがわかります。
残念ながら、私はここでどのように進むべきかわかりません。私はCythonを使うか、読み込みを行うためにCコードを書くことを考えています。Pypy antを試してみましたが、パフォーマンスは向上しましたが、残念ながらPypyで動作しない大きなプロジェクトと互換性がなければなりません。
フォーマット設定を削除し、マスクを読み取り値に直接使用します。 「文字列をビットに変換」フェーズをスキップします。ありがとう、 –
まあ、それは多くの意味があるようです。そうするためにquad2私は行データに沿って何かする必要があります= 00001111111111111100000000000000しかし、これをint16にキャストする方法がわかりません – dreichler
厳密には、1 kBは** 1024 ** B(1000ではない)です。 – CristiFati