2016-07-21 13 views
1

私は2つのshort intのセットを表す4バイトのバイナリ値を含むバイナリファイルを持っています。今、私はバッファ全体を解凍したいバイナリファイルバッファを2つの変数に展開する方法は?

from struct import unpack 

fval = b'\xba\x1e\x99\x01' #actualy read from some file 
qualdip, azi = unpack('hh', fval) 
print(type(qualdip), qualdip) 
print(type(azi), azi) 

>>> <class 'int'> 7866 
>>> <class 'int'> 409 

:私は、私はこのような二つの短い整数にシングル4バイトのバイナリ値を展開することができます知っています。現時点では私がやっている:

277メガバイトのファイルの分を引き継ぎ、巨大なメモリのオーバーヘッドを生み出すように見える
qualdips = [] 
azis = [] 
with open(bfile, 'rb') as buf: 
    fval = buf.read(4) 
    while fval: 
     qualdip, azi = unpack('hh', fval) 
     azis.append(azi) 
     qualdips.append(qualdip) 
     fval = buf.read(4) 

ファイルバッファ全体を2つの変数に直接展開したいと思います。これをどのように達成するのですか?

私はstruct.unpack_fromが私の友人だと思っていますが、フォーマットをどのように定式化するのかは分かりません。

with open(bfile, 'rb') as buf: 
    qualdip, azi = unpack_from('hh', buf) 

は2つのだけの値を抽出し、(私は私のファイルの要素の数を知っている)

with open(bfile, 'rb') as buf: 
    qualdip, azi = unpack_from('72457091h72457091h', buf) 

は、出力変数のこのとんでもない量を見込んでいます。したがって:

どのようにdo私はファイルバッファ全体を2つの変数に直接展開しますか?

+0

あなたはオーバーヘッドがどこにあるか見るためにあなたのコードをプロファイリングしましたか? I/O操作が最長時間を要している場合は、ファイルから大きなブロックで読み取ることができます。 – theorifice

答えて

1

私が直接、二つのリストに値を解凍する方法を知りませんが、あなたはタプルにファイル全体を解凍してから2でそれをスライスすることができます。また

fval = b'\xba\x1e\x99\x01' * 3 
unpacked= unpack('3h3h', fval) 
qualdip = unpacked[0::2] 
azi = unpacked[1::2] 

、作成にisliceを使用iteratorを使用すると、メモリ消費量を削減できます。

qualdip = islice(unpacked, 0, None, 2) 
azi = islice(unpacked, 1, None, 2) 
+0

isliceはイテレータオブジェクトだけを返しますが、実際の値が必要です。スライシングは素晴らしい作品です。私は 'qualdip = unpacked [0 :: 2]'、 'azi = unpacked [1 :: 2]'を使います。 – wsj

+0

私はそれに応じて答えを編集しましたが、答えの2番目のブロックで生成されたisliceオブジェクトから実際の値を取得する方法についてはわかりません。 – wsj

+0

@wsj 'islice'は[ジェネレータオブジェクト]です(http://stackoverflow.com/documentation/python/292/generators-yield#t=201607221128531431962)、あなたは' for value in azi: 'または'next(azi)'で値を一つずつ取得してください。 –

0

私は、これはそれを行うためのより高速な方法かもしれないと思う:

import os 
import struct 

def pairwise(iterable): 
    "s -> (s0,s1), (s2,s3), (s4, s5), ..." 
    a = iter(iterable) 
    return zip(a, a) 

bfile = 'bfile.bin' 
filesize = os.stat(bfile).st_size 
numvals = filesize // 2 

with open(bfile, 'rb') as bf: 
    fmt = '{}h'.format(numvals) 
    values = struct.unpack(fmt, str(bf.read())) 

qualdips, azis = zip(*pairwise(values)) 
関連する問題