Charger et enregistrer des données NumPy¶

Introduction¶

La capacité de lire et d'écrire des données est essentielle dans de nombreux projets scientifiques et d'analyse de données. NumPy fournit des fonctions pratiques pour lire et écrire des données dans divers formats.

Il est notamment possible de lire et sauver des vecteurs (ou matrices) NumPy à partir de :

  • Fichiers textes avec délimiteurs personnalisés
  • Fichiers CSV (Comma-Separated Values)
  • Fichiers images à divers formats (.jpg, .png, .tiff, ...)
  • Fichiers binaires

Manipulation de fichiers de données au format texte¶

Considérons le fichier data.txt suivant :

1 2 3
4 5 6
7 8 9

Nous allons utiliser la fonction np.loadtxt pour charger ce fichier texte.

In [1]:
import numpy as np

data = np.loadtxt("data.txt")
print(type(data), data.dtype, data.shape)
print(data)
<class 'numpy.ndarray'> float64 (3, 3)
[[1. 2. 3.]
 [4. 5. 6.]
 [7. 8. 9.]]

Vous pouvez contrôler les type de données charger par np.loadtxt.

In [2]:
data = np.loadtxt("data.txt", dtype=np.int32)
print(type(data), data.dtype, data.shape)
print(data)
<class 'numpy.ndarray'> int32 (3, 3)
[[1 2 3]
 [4 5 6]
 [7 8 9]]

Vous pouvez enregistrer une matrice NumPy dans un fichier texte via la fonction np.savetxt.

In [3]:
data[1, 1] = 5000
np.savetxt("data2.txt", data)

Manipulation de fichiers au format CSV (Comma Separated Value)¶

Considérons le fichier CSV suivant :

A,B,C
1,2,3
4,5,6
7,8,9

Vous pouvez aussi charger ce fichier via la même fonction, mais il faudra lui spécifier au moins deux arguments.

  • delimiter : permet de contrôler le séparateur de valeur (par défaut, l'espace).
  • skiprows : permet de ne pas considérer une ou plusieurs lignes. Dans notre cas, cela permettra de retirer la ligne de titre.

D'autres arguments peuvent aussi être spécifiés, et notamment :

  • dtype : permet de contrôler le type des données du tableau produit. Ce type sera le même pour toutes les lignes et les colonnes.
In [4]:
data = np.loadtxt("data.csv", delimiter=',', skiprows=1, dtype=np.int32)
print(type(data), data.dtype, data.shape)
print(data)
<class 'numpy.ndarray'> int32 (3, 3)
[[1 2 3]
 [4 5 6]
 [7 8 9]]

Une autre solution consiste à utiliser la fonction np.genfromtxt. Voici un premier exemple simple (notez l'utilisation du paramètre skip_header en lieu et place de skiprows.

data = np.genfromtxt("data.csv", delimiter=',', skip_header=1, dtype=np.float32) print(type(data), data.dtype, data.shape) print(data)

Comme ça vous pourriez penser que les deux fonctions sont identiques : il en est rien. La fonction np.genfromtxt est en fait bien plus puissante, car elle permet de contrôler le type de données colonne par colonne. Du plus, elle permet de gérer plus finement les valeurs manquantes dans le fichier CSV.

In [5]:
types = ["i4", "i8", "f8"]          # équivaut à [np.int32, np.int64, np.float64]
data = np.genfromtxt("data.csv", delimiter=',', skip_header=1, dtype=types)
print(type(data), type(data[0][0]), type(data[0][1]), type(data[0][2]))
print(data)
<class 'numpy.ndarray'> <class 'numpy.int32'> <class 'numpy.int64'> <class 'numpy.float64'>
[(1, 2, 3.) (4, 5, 6.) (7, 8, 9.)]

Changement d'images à l'aide de MatPlotLib¶

Vous pouvez facilement charger les valeurs des pixels d'une image dans un tableau NumPY. Mais pour y arriver, vous avez besoin d'une librairie supplémentaire : il en existe plusieurs et notamment MatPlotLib. C'est cette dernière que nous allons utiliser. Elle fournit la fonction plt.imread pour répondre à ce besoin.

In [6]:
import matplotlib.pyplot as plt
import numpy as np

img = plt.imread("bact2.png")
print(type(img), img.shape, img.dtype, img.max())
<class 'numpy.ndarray'> (1024, 1024, 3) float32 1.0

Comme vous le constatez, img est bien de type np.ndarray. L'image en question fait donc 1024 lignes par 1024 colonnes. Et comme nous avons à faire à une image RGB, nous récupérons trois plans de couleurs. La valeur maximale à 1 permet de comprendre que chaque valeur de pixels sera une valeur flottante comprise entre 0 et 1. Selon le format de fichier (.jpg, par exemple) vous pourrez récupérer des entiers (compris entre 0 et 255).

Vérifions l'image que nous venons de charger.

In [7]:
plt.imshow(img)
plt.show()

La fonction plt.imsave permet de réaliser l'opération inverse : la sauvegarde du tableau NumPy dans un fichier d'image.

In [8]:
plt.imsave("bact2.jpg", img)       # On sauvegarde l'image au format JPG (à l'origine un fichier PNG)
img = plt.imread("bact2.jpg")      # On recharge le nouveau fichier
print(img.shape, img.dtype)        # Cette fois-ci on manipule de entier non signés sur un seul octet.
(1024, 1024, 3) uint8

Manipulation de fichiers dans un format binaire¶

Voici les principaux formats binaires supportés par NumPy :

Format .npy : il s'agit d'un format de fichier binaire natif de NumPy pour stocker un seul tableau numpy.

  • Sauvegarde : np.save('file.npy', my_array)
  • Lecture : my_array = np.load('file.npy')

Format .npz : un format de fichier binaire pour stocker plusieurs tableaux numpy dans un seul fichier compressé.

  • Sauvegarde : np.savez('file.npz', array1=my_array1, array2=my_array2)
  • Lecture :
data = np.load('file.npz')
my_array1 = data['array1']
my_array2 = data['array2']
In [9]:
m = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
np.save("matrix.npy", m)