2009-04-30 14 views
20

mam listę wartości zmiennoprzecinkowych w Pythonie:Jak lista wyjście pływaków do pliku binarnego w Pythonie

floats = [3.14, 2.7, 0.0, -1.0, 1.1] 

chciałbym napisać te wartości do pliku binarnego z wykorzystaniem IEEE 32- kodowanie bitowe. Jaki jest najlepszy sposób na to w Pythonie? Moja lista zawiera około 200 MB danych, więc najlepiej "nie za wolno".

Ponieważ istnieje 5 wartości, po prostu chcę mieć plik 20 bajtów jako wynik.

+0

macierzy jest brakujące przecinki między numerami. –

Odpowiedz

30

Alex ma absolutną rację, to bardziej skuteczne, aby zrobić to w ten sposób:

from array import array 
output_file = open('file', 'wb') 
float_array = array('d', [3.14, 2.7, 0.0, -1.0, 1.1]) 
float_array.tofile(output_file) 
output_file.close() 

I następnie odczytać tablicę tak:

input_file = open('file', 'r') 
float_array = array('d') 
float_array.fromstring(input_file.read()) 

array.array obiekty mają również .fromfile sposobu, który może być wykorzystany do odczytu fi le, jeśli znasz liczbę przedmiotów z góry (np. od rozmiaru pliku lub jakiegoś innego mechanizmu)

+1

Czy pierwszy argument w tablicy nie powinien być literą "f", ponieważ wymagane jest 32-bitowe kodowanie? – dmagree

+0

FWIW, okazuje się, że odpowiedź struct jest w rzeczywistości szybsza. Zrobiłem profilowanie kilku różnych alternatyw, a struktura jest najszybsza przez całkiem sporo. https://gist.github.com/deanmalmgren/fd1714799dc5b5643b87#file-write_profiler-py – dino

12

zobacz: Python's struct module

import struct 
s = struct.pack('f'*len(floats), *floats) 
f = open('file','wb') 
f.write(s) 
f.close() 
+0

Właściwie to właśnie teraz robię. Po prostu myślałem, że musi być lepszy sposób. –

+1

I istnieje lepszy sposób - moduł tablicy. Zobacz http://docs.python.org/library/array.html dla wszystkich szczegółów. –

+0

Powinieneś użyć składni 'with'. –

10

moduł tablicy do standardowego biblioteki mogą być bardziej odpowiednie do tego celu niż moduł struct których każdy jest interpretowane. Wydajność z 200 MB danych powinna być znacznie większa w przypadku z macierzą.

Jeśli chcesz wziąć w różnych opcji, spróbuj profilowanie w systemie z something like this

8

Nie jestem pewien, w jaki sposób porówna się pod względem wydajności aplikacje, ale warto je zbadać.

Korzystanie NumPy:

from numpy import array 
a = array(floats,'float32') 
output_file = open('file', 'wb') 
a.tofile(output_file) 
output_file.close() 

wyniki w pliku 20 bajtów, jak również.

+1

nie tak szybko, jak przy użyciu struct. zobacz profilowanie tutaj https://gist.github.com/deanmalmgren/fd1714799dc5b5643b87#file-write_profiler-py – dino

1

Wpadłem na podobny problem, nieumyślnie wpisując plik CSV o wielkości 100 GB. Odpowiedzi tutaj były niezwykle pomocne, ale aby dojść do sedna, I profiled all of the solutions mentioned and then some. Wszystkie przebiegi profilowania zostały wykonane na komputerze Macbook Pro 2014 z dyskiem SSD za pomocą Pythona 2.7. Z tego co widzę, podejście struct jest zdecydowanie najszybszym z punktu widzenia wydajności:

6.465 seconds print_approach print list of floats 
4.621 seconds csv_approach  write csv file 
4.819 seconds csvgz_approach compress csv output using gzip 
0.374 seconds array_approach array.array.tofile 
0.238 seconds numpy_approach numpy.array.tofile 
0.178 seconds struct_approach struct.pack method 
Powiązane problemy