Je partage dans cet article 5 de mes méthodes de traitement de données avec Python préférées pour modifier des données.
Introduction : Traitement de Données avec Python
La popularité du langage de programmation Python est montée en flèche ces dernières années dans le domaine de la science des données (Data Science). Ce n’est pas sans raison, en effet Python fournit de nombreux outils prêts à l’emploi qui rendent le traitement et l’analyse des données, ainsi que l’apprentissage automatique (Machine Learning), très accessibles et faciles grâce à sa syntaxe ultra légère. Le tout, orchestré par l’incroyable écosystème qui est en place pour soutenir les capacités naturelles de Python dans ce domaine.
Le monde de la gestion des données en Python est vaste et en constante expansion, de sorte qu’il peut souvent être assez difficile de savoir exactement comment gérer chaque situation et maîtriser le traitement des données en Python. Cependant, il est possible de prendre ses dispositions avec des connaissances qui permettent de se préparer à peu près à tous les défis lorsqu’on travaille avec ce langage. Ceci étant dit, il existe quelques fonctions et modules simples qui peuvent certainement améliorer l’expérience de travail avec des données en Python.
Mapping
La première astuce dont je voulais vous parler est le mapping. En effet, à mon avis, le mapping est une méthode qui s’avère souvent très utile en Python. Cela est particulièrement vrai dans les scénarios où il y a beaucoup de données en jeu, car la méthode map peut être très efficace lorsqu’elle est utilisée pour résoudre (pratiquement) tous les problèmes liés aux données. En plus de tous ces avantages, la fonction est relativement simple à utiliser.
La première étape de l’utilisation de cette méthode consiste à créer une fonction qui doit être mappée. Pour ce faire, nous pouvons soit définir une nouvelle fonction comme nous le ferions normalement, soit utiliser une expression lambda de Python pour créer rapidement une fonction. En utilisant cette dernière, nous pouvons même compléter un appel de map en une seule ligne – ce qui rend le code de mapping potentiellement très concis tout en restant incroyablement puissant. Tout d’abord, nous devons noter que map ne fonctionne qu’avec des fonctions à un seul argument.
Considérons la liste suivante :
data = [5, 10, 15, 20]
Notre objectif avec cette liste est d’y associer une modification mathématique. Pour cet exemple, je vais utiliser l’addition de cinq.
Nous allons rapidement créer une fonction à cet effet :
def add5(x): return(x + 5)
Maintenant, si nous essayions d’introduire nos données dans cette fonction, nous obtiendrions une erreur car nous ne pouvons pas ajouter un entier à une liste. Notre objectif est d’effectuer cette arithmétique sur l’ensemble de notre liste, alors envisageons d’utiliser la méthode map(). La méthode map prendra la fonction que nous souhaitons mapper ainsi qu’un itérable comme arguments de position dans cet ordre.
newdata = map(add5, data)
Ceci retournera un nouveau type map. Nous pouvons ensuite transformer ce type en une liste avec le mapping appliqué en appliquant le type list sur ce mapping :
list(newdata)
Nous pourrions également effectuer cette même arithmétique en une seule ligne sans jamais écrire de fonction, en fournissant à la fonction une expression générée par lambda :
newdata = list(map(lambda x : x + 5, data))
Masques Pandas
La possibilité de masquer les observations avec des conditions à l’aide du module Pandas (pour Python) est un autre outil formidable pour le traitement des données. Ce module permet de passer un type de tableau de bits dans un appel de get index. En d’autres termes, nous pouvons indexer un DataFrame avec une condition afin de séparer les données en fonction des attributs. Cela est très utile, en particulier pour l’analyse de données. C’est un excellent moyen d’obtenir un échantillon d’une population rapidement et efficacement en une ligne de code Python simple et concise.
Considérons le DataFrame suivant :
import pandas as pd df = pd.DataFrame({"A" : [5, 10, 15, 20], "B" : ["grand", "petit", "grand", "petit"]})
Nous pourrions indexer ce DataFrame avec n’importe quelle instruction conditionnelle. Bien sûr, en termes de liste ou de de série Pandas, nous pouvons nous attendre à ce que tout opérateur de type booléen renvoie un tableau de bits. Un tableau de bits n’est autre qu’une liste de booléens.
Nous pouvons indexer les DataFrames Pandas à l’aide de ces tableaux de bits, comme suit :
a_filter = df[df["A"] > 10]
Et maintenant, regardez la tête de ce DataFrame :
a_filter.head()
Group By Pandas
Outre les masques conditionnels, Pandas dispose également d’un grand nombre de fonctions intéressantes intégrées à la classe DataFrame. L’un de ces outils est group by, qui permet d’ordonner les observations dans les données en fonction des classes ou du poids continu d’une certaine colonne.
Considérons le nouveau DataFrame suivant :
df = pd.DataFrame({'Animal': ['Faucon', 'Faucon', 'Perroquet', 'Perroquet'], 'Vitesse Max': [380., 370., 24., 26.]})
Nous pourrions regrouper toutes ces données par un attribut de ces différentes classes. Par exemple, nous pourrions condenser toutes nos classes de faucons et de perroquets en une seule observation basée sur la moyenne :
df.groupby(['Animal']).mean()
L’utilisation de cette fonction pourrait potentiellement faire gagner non seulement beaucoup de mémoire, mais aussi beaucoup de temps. Il va sans dire que l’analyse de la moyenne des différentes classes et de la façon dont les caractéristiques sont liées les unes aux autres peut être incroyablement utile pour comprendre véritablement la classification dans ces problèmes.
Par exemple, dans le DataFrame ci-dessus, nous aurions pu rapidement évaluer qu’un faucon vole considérablement plus vite qu’un perroquet.
L’alternative à cette fonction aurait été de rassembler ces caractéristiques dans des listes ou des DataFrames distincts, puis de calculer la moyenne par la suite. Inutile de dire que l’utilisation de la fonction groupby(), dans ce cas, a certainement permis de gagner beaucoup de temps.
Zip
Il arrive souvent, en programmation, que l’on veuille effectuer des opérations arithmétiques avec les dimensions de deux listes en même temps. Pour cela, Python nous fournit l’itérateur zip(). Cet itérateur prend deux arguments de position qui sont tous deux des itérables. Bien sûr, cela signifie que, puisque zip() est un itérateur, nous l’appellerons probablement avec une boucle itérative.
Considérons les deux listes suivantes :
a = [5, 10, 15, 20] b = [5, 10, 15, 20]
Nous allons prétendre que notre objectif est d’obtenir la somme de chaque dimension respective dans cette liste. Sans zip, cela serait probablement fait comme ceci en Python :
for it in range(0, len(a)): a[it] += b[it]
C’est une façon tout à fait valable de procéder. Cependant (c’est pas fou), cette approche peut laisser à désirer et peut rendre les choses beaucoup plus compliquées lorsqu’on travaille avec des données encore plus nombreuses que celles fournies dans cet exemple. L’alternative serait d’utiliser l’itérateur zip() pour combiner nos deux listes en un seul itérateur et de boucler sur nos deux listes en même temps.
empty = [] for ai, bi in zip(a, b): z = ai + bi empty.append(z)
Boucle sur une ligne
La dernière astuce Python que nous devrions tous examiner pour traiter nos données est le bouclage itératif en une ligne. La raison pour laquelle je pense qu’elle est très utile c’est surtout qu’elle est différente de la plupart des itérations. Dans la plupart des boucles itératives, nous n’attendons pas un retour de la boucle. Lorsqu’on procède de cette manière, cela change. Cela signifie que la liste vide que nous avons créée dans la boucle zip n’a pas vraiment besoin d’exister, et nous pouvons modifier cette boucle pour qu’elle boucle de cette manière afin d’éviter complètement d’avoir une boucle vide à laquelle ajouter des éléments.
Nous pouvons indiquer à Python que nous voulons faire cela en le délimitant par des crochets. À l’intérieur de ces crochets, nous écrivons notre boucle à l’envers. Cette méthode présente de nombreux avantages. Le premier avantage est celui que nous avons évoqué, à savoir un retour. Cependant, un autre avantage significatif de cette approche est également la vitesse et l’économie de mémoire tout en utilisant l’itération.
Recréons notre boucle zip ci-dessus en utilisant cette méthodologie :
empty = [ai + bi for ai, bi in zip(a, b)]
Il va sans dire qu’il y a de nombreuses situations où cela va s’avérer utile. Alors qu’en Python, nous pouvons probablement utiliser Pandas pour changer les types dans une série, il pourrait y avoir des situations où ces boucles seront même tout de même utiles juste pour le casting seul.
Conclusion : Traitement de Données avec Python
Les différentes approches énumérées dans cet article font partie des compétences Python les plus essentielles que vous pourriez apprendre pour le traitement des données. Non seulement elles se sont avérées très utiles dans mon expérience personnel, mais elles sont aussi un élément de base dans le monde de la programmation Python. Ne passez vraiment pas à côté 🙂
J’espère que cet article et les méthodes de traitement des données qu’il contient vous seront utiles !
Je vous recommande aussi ces articles :
- 10 astuces Pandas qui rendront votre travail plus efficace
- 12 techniques utiles de manipulation de données avec Pandas