2012-05-10 14 views
8

Chciałbym zapisać zawartość tablicy numpy float w surowym pliku binarnym jako 16-bitowe liczby całkowite ze znakiem. Próbowałem to osiągnąć, używając ndarray.tofile, ale nie mogę znaleźć odpowiedniego ciągu formatu. Wygląda na to, że plik jest zapisany w podwójnym formacie, niezależnie jak wybieram ciąg formatu. Jak mam to zrobic? Dzięki.Napisz surowy plik binarny z danymi tablicy NumPy

Odpowiedz

19

Myślę, że najprostszym sposobem, aby to zrobić, to najpierw przekonwertować tablicę do Int16,

array.astype('int16').tofile(filename) 
+1

Sieć [numpy dokumentacja] (http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.ndarray.tofile.html) stwierdza "Informacje o endianness i precyzji są tracone". Czy to działa na wszystkich platformach? – Gilly

+3

'tofile' zapisuje tylko surowe dane binarne tablicy, a nie metadane tablicy. Typowym przykładem użycia jest otwarcie pliku, napisanie odpowiedniego nagłówka dla danego typu pliku i użycie 'tofile' do wypełnienia nieprzetworzonych danych. Obowiązkiem oprogramowania czytającego plik jest wyprowadzenie metadanych (endianness, precyzja, kształt) z nagłówka i zmutowanie surowych danych do postaci odpowiedniej dla tej platformy. Bez metadanych nie ma możliwości prawidłowej interpretacji surowej zawartości tablicy. Jeśli potrzebujesz tylko czytać i zapisywać tablice, spójrz na "python hd5" lub "numpy.save". –

+0

Dziękujemy! Ten dodatkowy "astype" był potrzebny nawet wtedy, gdy utworzyłem tablicę określającą 'np.array ([], dtype = np.int8)'. –

8

Spójrz modułu struct, spróbuj ten przykład:

import struct 
import numpy 

f=open("myfile","wb") 
mydata=numpy.random.random(10) 
print(mydata) 
myfmt='f'*len(mydata) 
# You can use 'd' for double and <or> to force endinness 
bin=struct.pack(myfmt,*mydata) 
print(bin) 
f.write(bin) 
f.close() 
+10

Na podstawie doświadczenia zdecydowanie zalecam ** przeciw ** użycie 'struct.pack'. Jego API wymaga odznaczenia tablicy (tzn. Użycia operatora '*') na zmienne, które wpływają na wydajność ** drastycznie ** dla dużych rozmiarów macierzy. Każdy element tablicy będzie potrzebował nowego 64-bitowego wskaźnika (na maszynie 64-bitowej), który zostanie utworzony na stosie w celu wskazania tego elementu. Po prostu trzymaj się 'tostring' /' tobytes'/'tofile', aby uniknąć tego narzutu. Na przykład w naszym przypadku mieliśmy do czynienia z tablicami 100 Mb, co prowadzi do potężnego 6,4 GB pamięci RAM, więc 'struct.pack' może wykonać swoją pracę. –

0

Użytkownik może użyj scipy.io.savemat, który pozwala zapisać słownik nazw i tablic w pliku w stylu Matlaba:

import scipy.io as sio 
sio.savemat(filename, pydict) 

Tutaj pydict może być = { 'nazwa1': np.array1 'name2': np.array2, ...}

Aby załadować dict wystarczy:

pydict = sio.loadmat(filename)