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 :
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.
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
.
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
.
data[1, 1] = 5000
np.savetxt("data2.txt", data)
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.
D'autres arguments peuvent aussi être spécifiés, et notamment :
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.
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.)]
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.
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.
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.
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
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.
np.save('file.npy', my_array)
my_array = np.load('file.npy')
Format .npz : un format de fichier binaire pour stocker plusieurs tableaux numpy dans un seul fichier compressé.
np.savez('file.npz', array1=my_array1, array2=my_array2)
data = np.load('file.npz')
my_array1 = data['array1']
my_array2 = data['array2']
m = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
np.save("matrix.npy", m)