Python
Sort Pandas Dataframe

Tri facile des DataFrames Pandas: Guide pour débutants

MoeNagy Dev

Les bases du tri

Comprendre l'importance du tri dans l'analyse de données

Le tri des données est une opération fondamentale dans l'analyse de données et est souvent une étape cruciale dans la préparation des données pour leur traitement ultérieur, leur visualisation et la prise de décision. Le tri peut vous aider à :

  • Organiser les données de manière logique et significative
  • Identifier plus facilement les motifs et les tendances
  • Effectuer des recherches et des recherches de données efficaces
  • Faciliter l'analyse et la présentation des données
  • Améliorer la qualité et l'utilisabilité globale de vos données

Présentation de la méthode sort_values() dans Pandas

Dans Pandas, la méthode sort_values() est le moyen principal de trier un DataFrame. Cette méthode vous permet de trier le DataFrame en fonction d'une ou plusieurs colonnes, par ordre croissant ou décroissant.

import pandas as pd
 
# Créer un DataFrame exemple
df = pd.DataFrame({'Nom': ['Alice', 'Bob', 'Charlie', 'David'],
                   'Âge': [25, 30, 35, 40],
                   'Score': [85, 92, 78, 88]})
 
# Trier le DataFrame par la colonne 'Âge'
df_trié = df.sort_values(by='Âge')
print(df_trié)

Résultat :

     Nom  Âge  Score
0  Alice   25     85
1    Bob   30     92
2 Charlie   35     78
3  David   40     88

Tri par une seule colonne

Pour trier un DataFrame par une seule colonne, il suffit de passer le nom de la colonne au paramètre by de la méthode sort_values().

# Trier le DataFrame par la colonne 'Score' en ordre croissant
df_trié = df.sort_values(by='Score')
print(df_trié)

Résultat :

       Nom  Âge  Score
2 Charlie   35     78
0  Alice   25     85
3  David   40     88
1    Bob   30     92

Tri par plusieurs colonnes

Vous pouvez trier un DataFrame par plusieurs colonnes en passant une liste de noms de colonnes au paramètre by.

# Trier le DataFrame par 'Âge' en ordre croissant et 'Score' en ordre décroissant
df_trié = df.sort_values(by=['Âge', 'Score'], ascending=[True, False])
print(df_trié)

Résultat :

     Nom  Âge  Score
0  Alice   25     85
1    Bob   30     92
2 Charlie   35     78
3  David   40     88

Tri par ordre croissant et décroissant

Tri par ordre croissant

Par défaut, la méthode sort_values() trie le DataFrame par ordre croissant. Vous pouvez explicitement définir le paramètre ascending sur True pour trier par ordre croissant.

# Trier le DataFrame par 'Âge' en ordre croissant
df_trié = df.sort_values(by='Âge', ascending=True)
print(df_trié)

Résultat :

     Nom  Âge  Score
0  Alice   25     85
1    Bob   30     92
2 Charlie   35     78
3  David   40     88

Tri par ordre décroissant

Pour trier le DataFrame par ordre décroissant, définissez le paramètre ascending sur False.

# Trier le DataFrame par 'Âge' en ordre décroissant
df_trié = df.sort_values(by='Âge', ascending=False)
print(df_trié)

Résultat :

     Nom  Âge  Score
3  David   40     88
2 Charlie   35     78
1    Bob   30     92
0  Alice   25     85

Gestion des valeurs manquantes lors du tri

Pandas gère les valeurs manquantes (représentées par NaN) lors du tri en les plaçant soit au début, soit à la fin du DataFrame trié, en fonction du paramètre na_position.

# Créer un DataFrame avec des valeurs manquantes
df_avec_na = pd.DataFrame({'Nom': ['Alice', 'Bob', 'Charlie', 'David', 'Emily'],
                           'Âge': [25, 30, None, 40, 35],
                           'Score': [85, 92, 78, None, 88]})
 
# Trier le DataFrame par 'Âge', en plaçant les valeurs NaN au début
df_trié = df_avec_na.sort_values(by='Âge', na_position='first')
print(df_trié)

Résultat :

       Nom   Âge  Score
2  Charlie  NaN     78
3   David   40.0     NaN
4   Emily   35.0     88
0   Alice   25.0     85
1     Bob   30.0     92

Tri avec un ordre personnalisé

Tri basé sur un ordre prédéfini

Vous pouvez trier un DataFrame en fonction d'un ordre prédéfini des valeurs dans une colonne. Cela est utile lorsque vous souhaitez conserver un ordre spécifique, comme le tri par une variable catégorielle.

# Créer un DataFrame avec des données catégorielles
df = pd.DataFrame({'Catégorie': ['A', 'B', 'C', 'D', 'E']})
 
# Définir un ordre personnalisé pour la colonne 'Catégorie'
ordre_personnalisé = ['C', 'A', 'E', 'B', 'D']
 
# Trier le DataFrame par la colonne 'Catégorie' en utilisant l'ordre personnalisé
df_trié = df.sort_values(by='Catégorie', key=lambda x: pd.Categorical(x, categories=ordre_personnalisé, ordered=True))
print(df_trié)

Résultat :

  Catégorie
2       C
0       A
4       E
1       B
3       D

Utilisation du paramètre key dans sort_values()

Le paramètre key dans sort_values() permet d'appliquer une fonction de tri personnalisée à la ou aux colonnes que vous triez. Cela peut être utile lorsque vous avez besoin de réaliser des opérations de tri complexes.

# Trier le DataFrame par la longueur de la colonne 'Nom'
df_trié = df.sort_values(by='Nom', key=lambda x: x.str.len())
print(df_trié)

Résultat :

     Nom  Âge  Score
0  Alice   25     85
1    Bob   30     92
2 Charlie   35     78
3  David   40     88

Tri des données catégorielles

Travailler avec des données catégorielles dans Pandas

Pandas prend en charge les données catégorielles, ce qui peut être utile lors du tri des données. Les données catégorielles sont représentées comme un type de données spécial dans Pandas, vous permettant de préserver l'ordre et la signification des catégories.

# Créer un DataFrame avec des données catégorielles
df = pd.DataFrame({'Catégorie': pd.Categorical(['Élevé', 'Faible', 'Moyen', 'Élevé', 'Faible'], ordered=True)})
 
# Trier le DataFrame par la colonne 'Catégorie'
df_trié = df.sort_values(by='Catégorie')
print(df_trié)

Résultat :

    Category
1      Low
4      Low
2    Medium
0     High
3     High

Tri des colonnes catégorielles

Lors du tri d'un DataFrame par une colonne catégorielle, Pandas préserve l'ordre des catégories, même si les valeurs sous-jacentes sont des chaînes de caractères.

# Création d'un DataFrame avec des données catégorielles
df = pd.DataFrame({'Category': pd.Categorical(['High', 'Low', 'Medium'], ordered=True)})
 
# Tri du DataFrame par la colonne 'Category'
sorted_df = df.sort_values(by='Category')
print(sorted_df)

Sortie :

    Category
1      Low
2    Medium
0     High

Préservation de l'ordre des catégories

Si vous souhaitez conserver un ordre spécifique des catégories lors du tri, vous pouvez définir les catégories et leur ordre lors de la création des données catégorielles.

# Définition des catégories et de leur ordre
categories = ['Low', 'Medium', 'High']
 
# Création d'un DataFrame avec des données catégorielles et un ordre prédéfini
df = pd.DataFrame({'Category': pd.Categorical(['High', 'Low', 'Medium'], categories=categories, ordered=True)})
 
# Tri du DataFrame par la colonne 'Category'
sorted_df = df.sort_values(by='Category')
print(sorted_df)

Sortie :

    Category
1      Low
2    Medium
0     High

Tri des colonnes de type datetime

Manipulation des données datetime avec Pandas

Pandas offre une excellente prise en charge pour travailler avec des données datetime, y compris le tri par des colonnes datetime.

# Création d'un DataFrame avec des données datetime
import datetime
 
df = pd.DataFrame({'Date': [datetime.datetime(2022, 1, 1),
                           datetime.datetime(2022, 3, 15),
                           datetime.datetime(2021, 12, 31),
                           datetime.datetime(2022, 2, 28)]})
 
# Tri du DataFrame par la colonne 'Date'
sorted_df = df.sort_values(by='Date')
print(sorted_df)

Sortie :

           Date
2 2021-12-31 00:00:00
0 2022-01-01 00:00:00
3 2022-02-28 00:00:00
1 2022-03-15 00:00:00

Tri par colonnes datetime

Vous pouvez trier un DataFrame par une ou plusieurs colonnes datetime à l'aide de la méthode sort_values().

# Création d'un DataFrame avec plusieurs colonnes datetime
df = pd.DataFrame({'Date': [datetime.datetime(2022, 1, 1),
                           datetime.datetime(2022, 3, 15),
                           datetime.datetime(2021, 12, 31),
                           datetime.datetime(2022, 2, 28)],
                   'Time': [datetime.time(10, 30),
                           datetime.time(15, 45),
                           datetime.time(9, 0),
                           datetime.time(12, 0)]})
 
# Tri du DataFrame par 'Date' et 'Time'
sorted_df = df.sort_values(by=['Date', 'Time'])
print(sorted_df)

Sortie :

           Date     Time
2 2021-12-31 00:00:00  09:00:00
0 2022-01-01 00:00:00  10:30:00
3 2022-02-28 00:00:00  12:00:00
1 2022-03-15 00:00:00  15:45:00

Tri par composantes datetime

Vous pouvez également trier un DataFrame par des composantes individuelles d'une colonne datetime, telles que l'année, le mois, le jour, l'heure, la minute et la seconde.

# Tri du DataFrame par l'année de la colonne 'Date'
sorted_df = df.sort_values(by=pd.to_datetime(df['Date']).dt.year)
print(sorted_df)

Sortie :

           Date     Time
2 2021-12-31 00:00:00  09:00:00
0 2022-01-01 00:00:00  10:30:00
3 2022-02-28 00:00:00  12:00:00
1 2022-03-15 00:00:00  15:45:00

Techniques de tri efficaces

Optimisation des performances de tri

Le tri de grands DataFrames peut être intensif en termes de calcul, il est donc important de prendre en compte les performances lors du tri des données. Pandas offre plusieurs options pour optimiser les performances de tri.

# Tri du DataFrame inplace pour éviter de créer un nouveau DataFrame
df.sort_values(by='Age', inplace=True)

Utilisation du paramètre 'inplace'

Le paramètre 'inplace' dans sort_values() vous permet de modifier directement le DataFrame d'origine, plutôt que de créer un nouveau DataFrame. Cela peut être plus efficace en termes de mémoire, notamment lors du traitement de grands ensembles de données.

# Tri du DataFrame inplace pour éviter de créer un nouveau DataFrame
df.sort_values(by='Age', inplace=True)

Utilisation du paramètre 'ignore_index'

Le paramètre 'ignore_index' dans sort_values() permet de supprimer l'index d'origine du DataFrame après le tri. Cela peut être utile si vous n'avez pas besoin de conserver l'index d'origine et que vous souhaitez économiser de la mémoire.

# Tri du DataFrame et suppression de l'index d'origine
sorted_df = df.sort_values(by='Age', ignore_index=True)

Tri avec des index à plusieurs niveaux

Travailler avec des index à plusieurs niveaux dans Pandas

Pandas prend en charge les index à plusieurs niveaux (hiérarchiques), ce qui peut être utile lors du tri des données. Les index à plusieurs niveaux permettent d'organiser les données dans une structure plus complexe.

Tutoriel Python (Partie 2)

Fonctions

Les fonctions sont un concept fondamental en Python. Elles vous permettent d'encapsuler un ensemble d'instructions et de les réutiliser tout au long de votre code. Voici un exemple d'une fonction simple qui calcule l'aire d'un rectangle :

def calculate_area(length, width):
    area = length * width
    return area
 
# Appel de la fonction
rectangle_area = calculate_area(5, 10)
print(rectangle_area)  # Sortie : 50

Dans cet exemple, la fonction calculate_area prend deux paramètres, length et width, et retourne l'aire calculée. Vous pouvez ensuite appeler cette fonction avec différentes valeurs pour obtenir l'aire de différents rectangles.

Les fonctions peuvent également avoir des valeurs par défaut pour les paramètres et un nombre variable d'arguments :

def greet(name, message="Hello"):
    print(f"{message}, {name}!")
 
greet("Alice")  # Sortie : Hello, Alice!
greet("Bob", "Hi")  # Sortie : Hi, Bob!
 
def sum_numbers(*args):
    total = 0
    for num in args:
        total += num
    return total
 
print(sum_numbers(1, 2, 3))  # Sortie : 6
print(sum_numbers(4, 5, 6, 7, 8))  # Sortie : 30

Dans le premier exemple, la fonction greet a une valeur par défaut pour le paramètre message. Dans le deuxième exemple, la fonction sum_numbers peut accepter un nombre quelconque d'arguments, qui sont ensuite additionnés.

Modules et Packages

La bibliothèque standard de Python fournit une large gamme de modules intégrés que vous pouvez utiliser dans vos programmes. Vous pouvez également créer vos propres modules et packages pour organiser votre code.

Voici un exemple d'utilisation du module "math" :

import math
 
print(math.pi)  # Sortie : 3.141592653589793
print(math.sqrt(16))  # Sortie : 4.0

Vous pouvez également importer des fonctions ou des attributs spécifiques à partir d'un module :

from math import pi, sqrt
 
print(pi)  # Sortie : 3.141592653589793
print(sqrt(16))  # Sortie : 4.0

Pour créer votre propre module, vous pouvez simplement enregistrer un fichier Python avec l'extension .py. Par exemple, créons un module appelé my_module.py :

def greet(name):
    print(f"Bonjour, {name} !")
 
def calculate_area(longueur, largeur):
    return longueur * largeur

Vous pouvez ensuite importer et utiliser les fonctions de ce module dans votre script principal :

import my_module
 
my_module.greet("Alice")  # Sortie : Bonjour, Alice !
aire = my_module.calculate_area(5, 10)
print(aire)  # Sortie : 50

Les packages sont un moyen d'organiser vos modules dans une structure hiérarchique. Pour créer un package, vous devez créer un répertoire avec un fichier __init__.py. Voici un exemple :

my_package/
    __init__.py
    utils/
        __init__.py
        math_functions.py
        string_functions.py
    data/
        __init__.py
        database.py

Dans cet exemple, my_package est le package, et il contient deux sous-packages : utils et data. Chaque sous-package a un fichier __init__.py, qui peut être utilisé pour définir des fonctionnalités au niveau du package.

Vous pouvez ensuite importer et utiliser les fonctions des sous-modules de cette manière :

from my_package.utils.math_functions import calculate_area
from my_package.data.database import connect_to_db
 
aire = calculate_area(5, 10)
connexion_db = connect_to_db()

Programmation orientée objet (POO)

Python prend en charge la programmation orientée objet, ce qui vous permet de créer des classes et des objets personnalisés. Voici un exemple d'une classe simple Chien :

class Chien:
    def __init__(self, nom, race):
        self.nom = nom
        self.race = race
 
    def aboyer(self):
        print("Woof!")
 
# Création d'objets
mon_chien = Chien("Buddy", "Labrador")
print(mon_chien.nom)  # Sortie : Buddy
print(mon_chien.race)  # Sortie: Labrador
mon_chien.aboyer()  # Sortie : Woof!

Dans cet exemple, la classe Chien a une méthode __init__, qui est une méthode spéciale utilisée pour initialiser les attributs de l'objet. La méthode aboyer est une méthode personnalisée qui peut être appelée sur un objet Chien.

Vous pouvez également créer des relations d'héritage entre les classes :

class ChienGuide(Chien):
    def __init__(self, nom, race, niveau_formation):
        super().__init__(nom, race)
        self.niveau_formation = niveau_formation
 
    def guider(self):
        print("Je guide mon propriétaire !")
 
chien_guide = ChienGuide("Buddy", "Labrador", "avancé")
chien_guide.aboyer()  # Sortie : Woof!
chien_guide.guider()  # Sortie : Je guide mon propriétaire !

Dans cet exemple, la classe ChienGuide hérite de la classe Chien et ajoute un attribut niveau_formation et une méthode guider.

Exceptions et gestion des erreurs

Python offre un mécanisme solide de gestion des exceptions pour traiter les erreurs d'exécution. Voici un exemple de gestion d'une ZeroDivisionError :

def diviser(a, b):
    try:
        resultat = a / b
        return resultat
    except ZeroDivisionError:
        print("Erreur : Division par zéro.")
        return None
 
print(diviser(10, 2))  # Sortie : 5.0
print(diviser(10, 0))  # Sortie : Erreur : Division par zéro.

Dans cet exemple, la fonction diviser utilise un bloc try-except pour capturer la ZeroDivisionError et la gérer de manière appropriée.

Vous pouvez également créer vos propres exceptions personnalisées :

class ErreurSaisieInvalide(Exception):
    pass
 
def calculer_aire(longueur, largeur):
    if longueur <= 0 or largeur <= 0:
        raise ErreurSaisieInvalide("La longueur et la largeur doivent être des nombres positifs.")
    return longueur * largeur
 
try:
    aire = calculer_aire(5, 10)
    print(aire)  # Sortie : 50
    aire = calculer_aire(-5, 10)
except ErreurSaisieInvalide as e:
    print(e)  # Sortie : La longueur et la largeur doivent être des nombres positifs.

Dans cet exemple, la fonction calculer_aire génère une exception personnalisée ErreurSaisieInvalide si les valeurs d'entrée ne sont pas valides. Le bloc try-except capture et gère cette exception.

Conclusion

Dans ce tutoriel, vous avez appris divers concepts importants en Python, tels que les fonctions, les modules et les packages, la programmation orientée objet et la gestion des exceptions. Ces sujets sont essentiels pour la création d'applications Python plus complexes et robustes. N'oubliez pas de pratiquer et d'expérimenter avec les exemples de code fournis pour consolider votre compréhension. Bon codage !

MoeNagy Dev