2015-05-08 16 views
8

Mam plik binarny, który zawiera zapisy położenia płaszczyzny. Każdy rekord wygląd jak:Odczytaj plik binarny za pomocą Numpy fromfile i danego offsetu

0x00: Time, float32 
0x04: X, float32 // X axis position 
0x08: Y, float32 // Y axis position 
0x0C: Elevation, float32 
0x10: float32*4 = Quaternion (x,y,z axis and w scalar) 
0x20: Distance, float32 (unused) 

Więc każdy rekord to 32 bajtów.

Chciałbym uzyskać tablicę Numpy.

Przy przesunięciu 1859 znajduje się unsigned int 32 (4 bajty), które wskazują liczbę elementów tablicy. 12019 w moim przypadku.

Nie dbam (na razie) dane nagłówkowe (przed 1859) offsetowe

Array tylko zaczynają się od offsetu 1863 (= 1859 + 4).

zdefiniowałem własną NumPy dtype jak

dtype = np.dtype([ 
    ("time", np.float32), 
    ("PosX", np.float32), 
    ("PosY", np.float32), 
    ("Alt", np.float32), 
    ("Qx", np.float32), 
    ("Qy", np.float32), 
    ("Qz", np.float32), 
    ("Qw", np.float32), 
    ("dist", np.float32), 
]) 

I Czytam plik używając fromfile:

a_bytes = np.fromfile(filename, dtype=dtype) 

Ale nie widzę każdy parametr w celu zapewnienia, aby fromfile przekazać offset.

Odpowiedz

9

Możesz otworzyć plik z otwartym otwartym plikiem python, a następnie przejść do pominięcia nagłówka, a następnie przekazać obiekt pliku do fromfile. Coś takiego:

import numpy as np 
import os 

dtype = np.dtype([ 
    ("time", np.float32), 
    ("PosX", np.float32), 
    ("PosY", np.float32), 
    ("Alt", np.float32), 
    ("Qx", np.float32), 
    ("Qy", np.float32), 
    ("Qz", np.float32), 
    ("Qw", np.float32), 
    ("dist", np.float32), 
]) 

f = open("myfile", "rb") 
f.seek(1863, os.SEEK_SET) 

data = np.fromfile(f, dtype=dtype) 
print x 
+3

Dzięki. Rozwiązał mój problem. Zauważyłem również, że 'data = np.memmap (nazwa_pliku, dtype = dtype, tryb = 'r', offset = przesunięcie_tablica, kształt = N)' ' – scls

+1

w prawo, jeśli jest to duży plik, to memmapa może być sposobem udać się. – reptilicus

2

Stawiałem czoła podobnemu problemowi, ale żadna z powyższych odpowiedzi mnie nie satysfakcjonowała. Potrzebowałem zaimplementować coś w rodzaju wirtualnego stołu z bardzo dużą liczbą rekordów binarnych, które potencjalnie zajmowały więcej pamięci niż może sobie pozwolić w jednej tablicy numpy. Tak więc, moim pytaniem było, jak czytać i pisać mały zbiór liczb całkowitych z/do pliku binarnego - podzbiór pliku na podzbiór numpy array.

Jest to rozwiązanie, które pracował dla mnie:

import numpy as np 
recordLen = 10 # number of int64's per record 
recordSize = recordLen * 8 # size of a record in bytes 
memArray = np.zeros(recordLen, dtype=np.int64) # a buffer for 1 record 

# Create a binary file and open it for write+read 
with open('BinaryFile.dat', 'w+b') as file: 
    # Writing the array into the file as record recordNo: 
    recordNo = 200 # the index of a target record in the file 
    file.seek(recordSize * recordNo) 
    bytes = memArray.tobytes() 
    file.write(bytes) 

    # Reading a record recordNo from file into the memArray 
    file.seek(recordSize * recordNo) 
    bytes = file.read(recordSize) 
    memArray = np.frombuffer(bytes, dtype=np.int64).copy() 
    # Note copy() added to make the memArray mutable 
Powiązane problemy