Python : Comment sauvegarder des tableaux NumPy

 

Dans ce tutoriel, nous allons apprendre à sauvegarder des tableaux numpy pour ajouter de la persistance à votre application python.

Notre première persistance

Sauvegarde des données

Pour sauvegarder votre tableau NumPy, on utilise le comportement natif de python pour l’ouverture d’un fichier, et on appelle la fonction save de NumPy :

import numpy as np

array = np.array([6, 9])

with open('array.npy', 'wb') as f:
    np.save(f, array)

Le fichier en sortie utilise un format binaire spécifique numpy. Sur la première ligne, on trouve les paramètres de notre tableau persisté :

�NUMPYv{'descr': '<i8', 'fortran_order': False, 'shape': (2,), }

La suite du fichier est composée d’octets correspondant aux valeurs du tableau.

Chargement des données

Après avoir sauvegardé nos données, il faut pouvoir les charger. Pour cela, on utilise la fonction load de numpy :

with open('array.npy', 'rb') as f:
    array2 = np.load(f)
    print(array2)

Ce qui donne le résultat suivant :

[6 9]

Et voilà, on a notre première persistance de données avec numpy !

Persistance au format texte

Il arrive qu’on veuille utiliser des données traitées avec numpy dans un autre langage de programmation, ou par exemple sur excel. On doit donc enregistrer nos données dans un format compréhensible par tous.

Sauvegarde des données

On utilise une autre fonction de numpy savetxt :

array = np.array([[6, 9, 42], [4, 2, 9]])
np.savetxt('array_float.csv', array, delimiter=',')

Le delimiter est le caractère au sein du fichier qui séparera nos valeurs. Les délimiteurs courants sont , et ;.

Notre fichier csv contient :

6.000000000000000000e+00,9.000000000000000000e+00,4.200000000000000000e+01
4.000000000000000000e+00,2.000000000000000000e+00,9.000000000000000000e+00

Les nombres sont enregistrés par défaut en nombre flottant, pour régler ça, on spécifie un format à notre export :

np.savetxt('array_int.csv', array, delimiter=',', fmt='%i')

Finalement, on obtient un format en entier :

6,9,42
4,2,9

Chargement des données

Maintenant pour charger nos données enregistrées en format texte, on utilise loadtxt :

array_loaded_from_text = np.loadtxt('array_int.csv', delimiter=',')
print(array_loaded_from_text)
[[ 6.  9. 42.]
 [ 4.  2.  9.]]

Compression en archive gz

Si la quantité de données est conséquente, il peut être intéressant de compresser les données enregistrées. La fonction de sauvegarde utilisée précédemment savetxt permet de compresser nativement les données, si le fichier de sortie possède l’extension .gz (pour gzip ou GNU zip).

big_array = np.random.rand(1000, 1000) # tableau de 1000x1000
np.savetxt('array_test.csv', big_array, delimiter=',')
np.savetxt('array_compressed.gz', big_array, delimiter=',')
Fichier Taille
.csv ~25,0 Mo
.gz ~10,6 Mo

Le gain de place est intéressant (le fichier compressé est plus de deux fois plus petit), cependant l’enregistrement et le chargement des données sauvegardées au format gz seront plus longs. Notez que sur des données aléatoires comme ici, la compression est loin d’être optimale : sur des données réelles, souvent plus régulières, le gain est généralement meilleur.

Le chargement se fait de la même façon que précédemment, la fonction loadtxt se charge de décompresser pour nous les données.

big_array_loaded = np.loadtxt('array_compressed.gz', delimiter=',')

Persistance au format npz

NumPy propose une dernière façon de persister vos données avec le format npz, qui a l’avantage de pouvoir sauvegarder plusieurs tableaux numpy dans le même fichier et contrairement au format texte, ce format supporte des tableaux à n dimensions.

np.savez('test.npz', array=array, big_array=big_array)
loaded_npz = np.load('test.npz')
array_loaded_from_npz = loaded_npz['array']
big_array_loaded_from_npz = loaded_npz['big_array']

print(loaded_npz.files)
print(big_array_loaded_from_npz.shape)

Ce qui donne :

['array', 'big_array']
(1000, 1000)

De plus, NumPy propose avec le format npz de compresser facilement les données :

np.savez_compressed('test_compressed.npz', array=array, big_array=big_array)
loaded_npz = np.load('test_compressed.npz')
array_loaded_from_npz = loaded_npz['array']
big_array_loaded_from_npz = loaded_npz['big_array']

Comme pour loadtxt la fonction load se charge de décompresser automatiquement.

Conclusion

Voilà, vous êtes maintenant capable de faire persister vos données numpy.

Voir aussi