Comment afficher la liste des floats dans un fichier binaire en Python
j'ai une liste de valeurs à virgule flottante en Python:
floats = [3.14, 2.7, 0.0, -1.0, 1.1]
je voudrais écrire ces valeurs dans un fichier binaire en utilisant l'encodage IEEE 32 bits. Quelle est la meilleure façon de faire cela en Python? Ma liste contient environ 200 MO de données, donc quelque chose de "pas trop lent" serait mieux.
Puisqu'il y a 5 valeurs, je veux juste un fichier de 20 octets comme sortie.
7 réponses
Alex a absolument raison, c'est plus efficace de le faire de cette façon:
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()
Et puis lire le tableau comme ça:
input_file = open('file', 'r')
float_array = array('d')
float_array.fromstring(input_file.read())
array.array
les objets ont également un .fromfile
méthode qui peut être utilisé pour lire le fichier, si vous connaissez le nombre d'éléments à l'avance (par exemple, de la taille du fichier, ou un autre mécanisme)
Voir: module struct de Python
import struct
s = struct.pack('f'*len(floats), *floats)
f = open('file','wb')
f.write(s)
f.close()
le module array dans la bibliothèque standard peut être plus adapté à cette tâche que le module struct que tout le monde suggère. La Performance avec 200 Mo de données devrait être substantiellement mieux avec le tableau.
Si vous souhaitez emmener à une variété d'options, essayez le profilage sur votre système avec quelque chose comme ceci
Je ne suis pas sûr comment num Py comparera les performances de votre application, mais cela peut valoir la peine d'être étudié.
en utilisant num Py:
from numpy import array
a = array(floats,'float32')
output_file = open('file', 'wb')
a.tofile(output_file)
output_file.close()
donne aussi un fichier de 20 octets.
j'ai rencontré un problème similaire en écrivant par inadvertance un fichier csv de 100+ Go. Les réponses données ici ont été extrêmement utiles, mais, pour aller au fond de lui, je profilé toutes les solutions mentionnées et puis certains. Toutes les opérations de profilage ont été effectuées sur un Macbook Pro 2014 avec un SSD utilisant python 2.7. À partir de ce que je vois, le struct
approche est certainement le plus rapide à partir d'un point de vue des performances:
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