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.

21
demandé sur dbr 2009-04-30 20:35:43

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)

32
répondu Nadia Alramli 2009-04-30 18:04:14

Voir: module struct de Python

import struct
s = struct.pack('f'*len(floats), *floats)
f = open('file','wb')
f.write(s)
f.close()
15
répondu thesamet 2009-04-30 16:39:05

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

10
répondu Alex Martelli 2015-12-08 19:24:19

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.

8
répondu Grant 2009-04-30 21:33:52

regardez struct.pack_into

3
répondu SilentGhost 2009-04-30 16:38:02

struct.pack() ressemble à ce dont vous avez besoin.

http://docs.python.org/library/struct.html

3
répondu joshdick 2009-04-30 16:40:14

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
1
répondu dino 2015-12-08 19:15:14