2017-12-02 8 views
0

16進形式で格納された.binファイルからデータを解析するためにpythonを使用しようとしています。残念ながら、データを取得するためには、16進数を10進数に変換するだけでは簡単ではありません。6桁のデータブロックを解析し、データフレームに10進数値を格納する

このファイルには、「測定値」が6つの変数(X軸、Y軸、Z軸、測光器、ボタンステータス、および予約済み)の値を含む6バイトデータの6バイトブロックスペース(空のスペース)。

各軸は12ビット(つまり1.5バイト)をカバーし、ライトは10ビットをカバーし、ボタンステータス/スペアはそれぞれ1ビットです。例えば

生データ(6バイト):F4 1F 9E 08 20 00( 'ページ' ごとに繰り返さ300X)

X軸(12bits)= F4 1

Y軸(12bits)= F 9E

Z軸(12bits)= 08 2

光(10ビット)= 0 0(および最終0の最初の2ビット)

ボタン(1ビット)= 2リザーブ

0最終(1ビット)=最終 0

の最後のビットの最後のビットに

ファイルを解析し、ブロックを変数に分割し、16進数を10進数に変換するにはどうすればよいでしょうか?変数を列として、各小節(すなわち、6バイトブロック)を行として、小数値のデータフレームを有することを目指す。

以下の通常のオープン/リードコードを過ぎていると、これに最も近づく方法がわかりません。

with open(<PATH>, 'r') as f: 
    data = f.read() 
+0

私はしかし、私はあなたには、いくつかの[ヒント]を得ることができると考え、これらの事を知っていると主張していませんよ(https://stackoverflow.com/questions/47561251/how-to-convert-a- raw-hexadecimal-image-to-a-html-img/47561725#comment82081925_47561725)他から同様の質問。私はあなたがnumpyがインストールされていると仮定します。 – ahed87

+0

私はあなたのファイルが16進文字ではなくバイナリデータを含んでいないと賭けています。もしそうなら、[this](https://stackoverflow.com/questions/1035340/reading-binary-file-and-looping-over-each-byte)のような何かが助けになるかもしれない – FujiApple

答えて

0

あなたはビットにバイナリデータを読み込むための最善の方法は、おそらくnumpy.fromfileなり、その後、np.unpackbitsが続くでしょう

with open(...) as f: 
    for line in f: 
     # remove all white spaces 
     hex = line.replace(" ", "") 

     # convert fist 12 bits into int 
     x = int(hex[0:3], 16) 

     # second 
     y = int(hex[3:6], 16) 

     # third 
     z = int(hex[6:9], 16) 

     # convert last 12 bits from HEX to BIN (add padding to make sure you always have 12 figures) 
     # get first 10 bits and convert to int 
     light = int('{:012b}'.format(int(hex[9:12],16))[0:10],2) 
     # get bit 11 
     button = int('{:012b}'.format(int(hex[9:12],16))[10:11],2) 
     # get last bit 
     reserved = int('{:012b}'.format(int(hex[9:12],16))[11:12],2) 
+0

それは明らかではないが、私はファイルを疑う16進数の文字は含まれていませんが、元のバイナリデータ – FujiApple

+1

です。この場合、この脅威を考慮してください。https://stackoverflow.com/questions/8710456/reading-a-binary-file-with-python – Thomas

0

を試すことができます。配列になります

uint_arr = np.fromfile(<PATH>, dtype = "uint8") 
bit_arr = np.unpackbits(uint_arr) 

bit_arr 1と0のそこから、我々はreshapeとの6つのバイトの対応にビットを分割したい:

bit_arr = bit_arr.reshape(-1, 48) 
0

まず私はあなたの入力ファイルがバイナリデータではなく文字データ(すなわち進文字)が含まれてと仮定しています。

ファイル形式がバイト境界(3x12ビット、次に1x10ビット、2x1ビット)で整列されていないことが原因で、少しのジヤイリングが必要です。

我々は、単一の測定のためのフォーマットを調べると、我々はこれを持っている:

# 0xF4  0x1F  0x9E  0X08  0x20  0x00 
# --------- --------- --------- --------- --------- ------------ 
# 0xF 0x4 0x1 0xF 0x9 0xE 0x0 0x8 0x2 0x0 0x0 0x0 
# 1111 0100 0001 1111 1001 1110 0000 1000 0010 0000 0000 00 0 0 

私たちが望むアライメントがある:

#  x-axis   y-axis  z-axis   light  b r 
# -------------- -------------- -------------- ------------ - - 
# 1111 0100 0001 1111 1001 1110 0000 1000 0010 0000 0000 00 0 0 

そこであなたは、我々はいくつかのビットを行う必要があるしたいの解釈を取得します操作。下記(これは簡素化を助けるために可能性の高いAPIがあります)この長い手を行う方法を示しています

MEASURE_SIZE_BYTES = 6 
MEASURES_PER_PAGE = 300 
PAGE_SIZE_BYTES = MEASURE_SIZE_BYTES * MEASURES_PER_PAGE 

def readPage(data): 
    measures = [] 
    for measure in xrange(0, MEASURES_PER_PAGE): 
     i = measure * MEASURE_SIZE_BYTES 
     xAxis = (data[i] << 4) + (data[i + 1] >> 4) 
     yAxis = ((data[i + 1] & 0xF) << 8) + (data[i + 2]) 
     zAxis = (data[i + 3] << 4) + (data[i + 4] >> 4) 
     light = ((data[i + 4] & 0xF) << 8) + (data[i + 5] & 0xFC) 
     button = (data[i + 5] & 0x2) >> 1 
     reserved = (data[i + 5] & 0x1) >> 0 
     measures.append({'xAxis': hex(xAxis), 'yAxis': hex(yAxis), 
         'zAxis': hex(zAxis), 'light': hex(light), 
         'button': hex(button), 'reserved': hex(reserved)}) 
    return measures 

with open("data.bin", 'rb') as f: 
    pages = [] 
    pageBytes = bytearray(f.read(PAGE_SIZE_BYTES)) 
    while len(pageBytes) == PAGE_SIZE_BYTES: 
     pages.append(readPage(pageBytes)) 
     pageBytes = bytearray(f.read(PAGE_SIZE_BYTES)) 
    print(pages) 

は(単一ページ/メジャーの)生成されます

[[{'reserved': '0x0', 'yAxis': '0xf9e', 'light': '0x0', 'button': '0x0', 'zAxis': '0x82', 'xAxis': '0xf41'}]] 

結果を表示するにはbase10で:

[[{'button': 0, 'light': 0, 'reserved': 0, 'xAxis': 3905, 'yAxis': 3998, 'zAxis': 130}]] 
+0

私はそれが 'light =((data [i + 4]&0xF)<< 6)+((data [i + 5]&0xFC)>> 2)'であるべきだと思う。今すぐ検証する時間がありません(どちらの場合も0であるため、あなたの例で動作します)。あなたがこれを必要とするなら、私に知らせてください。そして私は明日それを確認することができます。 – FujiApple

関連する問題