On ne pose pas de cookies de suivi nous-mêmes. Les vidéos de cours sont hébergées sur YouTube, qui dépose ses propres cookies dès qu'une vidéo se charge — elles restent disponibles en un clic si vous préférez ne pas les accepter maintenant.
Changer la forme d'un tableau (reshape / stack) · Python — Sup2Tech
Changer la forme d'un tableau (reshape / stack)
0/6
Vidéo
Étape 1 sur 4, Vidéo
NumPy : slicing, reshaping et indexation avancée
Points clés de cette vidéo
.reshape() réorganise un array existant en une nouvelle forme (ex : une liste plate en tableau 2D), sans changer les données ni leur ordre
Le nombre total d'éléments doit rester identique — impossible de reshaper 6 éléments en une forme 2x4 (8 cases)
Utile pour adapter une donnée au format attendu par une autre fonction ou un autre outil
Transcription de la vidéo
Nous avons introduit dans une précédente vidéo la notion de tableau NumPy. Dans cette vidéo, nous allons parler de slicing que l'on peut appliquer aux tableaux NumPy, de la notion de reshaping qui permet de redimensionner des tableaux NumPy, et de la notion d'indexation avancée qui permet de sélectionner des éléments dans un tableau de manière expressive et efficace. Ouvrons maintenant un notebook pour commencer à jouer avec ces différentes notions. Commençons par créer un tableau NumPy constitué d'entiers choisis au hasard. Donc ici je vais écrire a égale np.random.randint donc random.randint(), c'est une méthode qui nous permet de générer des nombres aléatoires de 1 à 10 et ici, je vais spécifier la shape de mon tableau donc ça va être un tableau 3x3. Ici, c'est quelque chose qui peut être un petit peu agaçant et c'est quelque chose qui est un signe du manque de maturité de NumPy, nous avons vu dans une précédente vidéo que pour ones, la fonction ones, on utilisait l'argument shape pour définir la taille d'un tableau ; ici, dans random.randint, on utilise l'argument size. En fait, c'est exactement le même sens, c'est pour définir les dimensions de mon tableau. Donc ici, j'exécute ça, je regarde mon tableau et ici, j'ai un tableau 3x3 qui contient des nombres aléatoires allant de 1 à 10. Donc en NumPy, on peut faire du slicing, exactement comme ce que l'on ferait avec des listes, avec la même sémantique. Regardons cela. Je vais prendre a de 1 deux points à 2 deux points et donc c'est exactement le même sens qu'un slicing classique sur les listes, je vais de i à j moins 1 par pas de k. Mais ici évidemment, comme j'ai deux coordonnées je vais faire un slice sur les lignes et un slice sur les colonnes. Regardons le résultat de ce slice. J'obtiens un nouveau tableau. Alors le point très important du slicing sur les tableaux NumPy, c'est qu'en fait ce slice ne va pas vous retourner réellement un nouveau tableau, il va uniquement vous retourner une vue sur le tableau existant. Donc en fait, on ne crée pas de structure de données supplémentaire. Regardons cela. Je vais définir b égal à a de 1 deux points, virgule deux points 2 alors, b est égal à cela. Je regarde mon sous-tableau b et maintenant, je vais dire a de 1 virgule 1 égale 35. Je modifie la valeur de l'élément 1, 1 dans le tableau a. Et maintenant, donc évidemment, mon tableau a a été modifié, l'élément central vaut maintenant 35, mais si je regarde mon tableau b, mon tableau b a également été modifié. Pourquoi ? Parce qu'en fait il s'agit simplement d'une vue sur le tableau original. En fait, c'est toujours le même principe : en NumPy, on a une zone contiguë de mémoire et on travaille sur cette zone contiguë de mémoire. Maintenant, regardons une autre caractéristique des tableaux NumPy, c'est la possibilité de changer leurs dimensions, le reshaping avec la méthode reshape. Regardons cela. Je vais créer un tableau a toujours aléatoire random.randint 1, 10 virgule size égale 4, 4. Ici, je crée un tableau 4x4 quatre lignes, quatre colonnes. Et maintenant, je peux redimensionner ce tableau Comment je fais ça ? Je fais ça de la manière suivante : b égale a.reshape et ici, je vais donner une nouvelle dimension et il faut évidemment que le nombre d'éléments dans le tableau original soit le même que dans le tableau qui a été redimensionné. Regardons maintenant mon redimensionnement avec huit lignes et deux colonnes. Ici, de nouveau, reshape ne va pas vous retourner un nouveau tableau mais va simplement vous retourner une vue sur le tableau original. Nous allons maintenant parler de la notion de tableau booléen. Donc ici, prenons un exemple, un tableau qui représenterait les températures du mois de mars qui iraient de -5 à 20 degrés. Prenons cet exemple, je vais écrire mars égale np.random.randint de -5 à 20 et ici, size égale 31. Donc c'est un tableau à une dimension qui contient trente-et-un éléments. J'exécute et je vois bien mon tableau de températures. Maintenant, regardons quelles températures sont strictement positives. Pour cela, je peux utiliser l'opérateur de comparaison mars strictement positif qui va effectuer une opération vectorisée nous reviendrons sur cette notion de vectorisation dans une prochaine vidéo mais sachez simplement que c'est une opération qui est très efficace et qui va me produire quelque chose que l'on appelle un tableau de booléens. L'élément 15 est strictement positif donc ici, dans mon tableau de booléens, j'ai True. L'élément -4 est négatif, donc dans mon tableau de booléens, j'ai False et j'applique donc cette comparaison à chaque élément de mon tableau. On peut utiliser, pour les comparaisons, n'importe quel opérateur supérieur, supérieur ou égal, inférieur, inférieur ou égal, égal, donc c'est égal égal, ou différent. Ces tableaux de booléens sont extrêmement utiles. Regardons un autre exemple. Je vais faire mars égal égal à zéro : est-ce que j'ai des températures nulles dans mon tableau ? ici, je n'en ai pas. Vous pouvez vous demander maintenant, j'ai mon tableau de booléens mais qu'est-ce que j'en fais de ce tableau de booléens ? En fait, ce tableau de booléens a deux usages. Le deuxième usage qu'on verra dans quelques instants, c'est l'indexation avancée mais le premier usage, c'est lié à la constatation que True vaut 1 et que False vaut 0. Regardons à quoi ça nous sert. Supposons que je me pose la question suivante : Pour combien de jours il a fait une température positive en mars ? Je peux le savoir en faisant l'opération suivante : np.sum de mars strictement positif. mars strictement positif va me générer un tableau de booléens, qui va être True uniquement quand c'est strictement positif, et donc True vaut 1, et False vaut 0, et donc, en faisant la somme, j'ai le nombre de jours où il a fait une température strictement positive en mars. Maintenant, imaginons que je me pose une autre question : est-ce qu'il y a eu au moins un jour au mois de mars où il a fait 20 degrés ? Pour cela, je vais utiliser any qui va me retourner vrai si j'ai au moins un True dans mon tableau de booléens. Ici, je fais mars égal égal à 20 degrés et donc, regardons ça : non, il n'y a eu aucun jour en mars où il a fait exactement la température 20 degrés. Et regardons un dernier cas : np.all mars strictement positif qui va me servir à répondre à la question : est-ce que, pour tous les jours du mois de mars, il a fait une température strictement positive ? La réponse est non. Donc voyez qu'en manipulant ces tableaux de booléens avec ces opérations d'agrégation on peut déjà répondre à des questions intéressantes. Maintenant, j'aimerais vous montrer comment est-ce qu'on peut combiner les tableaux de booléens entre eux, en utilisant les opérateurs ET, OU et NOT. Regardons un exemple. Avant d'aller plus loin, je vais créer un tableau jours du mois de mars qui va être égal à np.arange qui me permet, comme la fonction built-in range, de générer une suite d'entiers ici allant de 1 à mars.size donc le nombre d'éléments que j'ai dans mars dans le mois de mars plus un et ici, je vais spécifier mon dtype parce que je vous rappelle que c'est toujours une bonne pratique de maîtriser son dtype, ici, je vais mettre un dytpe à int8. Je regarde jours du mois de mars, qu'est-ce que ça contient ? Et bien, ça contient juste les entiers allant de 1 à 31. Et maintenant que j'ai ce tableau des jours du mois de mars, je peux combiner un opérateur booléen sur ces jours avec un opérateur booléen sur le mois de mars directement. Regardons donc un exemple : Je vais faire np.sum qui va me permettre de répondre à la question suivante : je vous montre ça je fais mars strictement supérieur à 10 combien de jours, au mois de mars, il a fait plus de 10 degrés ? et je rajoute l'opérateur ET et ici, je vais mettre jours du mois de mars supérieur ou égal à 15 donc ça veut dire quoi ? Je vais calculer le nombre de jours où il a fait plus de 10 degrés pour les jours qui ont été après le 15 mars. Ici, il faut noter plusieurs choses importantes Regardons le résultat, c'est 7. Notons plusieurs choses importantes. La première chose, c'est que mon opérateur logique ET ici, c'est un opérateur bitwise. En effet, comme je manipule des tableaux de bits, je dois appliquer un opérateur bitwise et non plus l'opérateur classique AND, OR ou NOT. Deuxième chose qu'on remarque, c'est que j'ai entouré par des parenthèses mars supérieur à 10 et jours de mars supérieur ou égal à 15 Pourquoi ? Parce que l'opérateur ET est le plus prioritaire et par conséquent, si l'on veut que notre opération fasse ce que l'on souhaite il faut obligatoirement entourer ce qu'il y a à gauche et ce qu'il y a à droite de notre opérateur bitwise par des parenthèses. Maintenant que l'on connaît les tableaux de booléens, ça serait intéressant de les appliquer à des tableaux existants pour faire ce qu'on appelle de l'indexation avancée. Regardons cet exemple. C'est quelque chose qui permet d'obtenir des sous-ensembles de tableaux de manière extrêmement expressive. Ici, je vais prendre mon tableau du mois de mars et comme indice, je vais lui passer directement un tableau de booléens. Et donc je vais passer mars strictement supérieur à 10. Que va faire cette opération ? Elle va sélectionner dans le tableau mars uniquement les valeurs pour lesquelles la température est strictement supérieure à 10 degrés. J'obtiens donc un nouveau tableau qui est un sous-ensemble du tableau original. Je peux également évidemment passer comme indice avancé des expressions booléennes combinées avec des opérateurs logiques. Par exemple, je vais passer mars strictement supérieur à 10 degrés et jours de mars supérieur ou égal à 15, donc retourne-moi, dans le tableau mars, toutes les températures supérieures à 10 degrés après le 15 mars et donc voici les températures que j'obtiens. Sur ces opérations d'indexation avancée, je peux également faire de l'affectation. Faisons une hypothèse. Supposons qu'en fait au mois de mars, nous savons qu'il y a forcément des températures positives et que toutes les températures négatives soient simplement dues à des erreurs de mesure avec notre instrument. À ce moment-là, je peux remplacer toutes les valeurs négatives par, par exemple, la moyenne des températures positives. Regardons cet exemple. Ici, je vais calculer moyenne égale np.mean donc je vais calculer avec NumPy la moyenne du mois de mars pour lequel les températures sont strictement positives. Ça, ça va donc me donner une moyenne. Et ensuite, je vais faire mars pour les températures qui sont strictement négatives donc mes erreurs de mesure, je vais les remplacer par la moyenne. J'exécute. Et maintenant, je vais regarder mon tableau du mois de mars et dans mon tableau du mois de mars, je vois maintenant que je n'ai plus aucune température négative et les températures négatives ont été remplacées par la moyenne sur les jours sur lesquels il a fait une température positive. Pour finir de parler de l'indexation avancée, j'aimerais vous montrer une dernière possibilité, c'est la possibilité suivante, ici, je vais créer un tableau que je vais appeler countries qui va être égal à np.array et ici, je vais passer le tableau suivant qui va contenir fr, us japon. Et maintenant, je vais pouvoir construire un nouveau tableau à partir de ces valeurs-là en passant à countries une liste d'indices. Et ici, je vais lui passer 0 virgule 0, ça veut dire que je vais avoir deux fois fr, je vais lui passer 1, 2 et 0. Donc ça me permet à partir d'un tableau original, countries, de récupérer les éléments du tableau et de créer un nouveau tableau dans lequel je peux même avoir des éléments dupliqués. Regardons le résultat de cette évaluation : je vais avoir deux fois fr, une fois us, une fois japon et une fois fr. Dans cette vidéo, nous avons vu les notions de slicing et de reshaping qui permettent de générer des vues sur des tableaux existants et nous avons surtout vu la notion d'indexation avancée à partir de masques. C'est une opération qui est extrêmement puissante et qu'il faut prendre le temps de bien maîtriser. À bientôt !