Skip to content
Thèmes
Pandas
Pandas Filter Rows: Select Data by Condition in Python

Filtrer les Lignes Pandas : Sélectionner les Données par Condition en Python

Updated on

Filtrer les lignes dans les DataFrames pandas est l'une des opérations les plus courantes en analyse de données. Que vous nettoyiez des données, exploriez des motifs ou prépariez des ensembles de données pour l'apprentissage automatique, vous devez sélectionner des lignes spécifiques en fonction de conditions. Le défi consiste à choisir la bonne méthode parmi les multiples approches de filtrage de pandas, chacune avec une syntaxe, des caractéristiques de performance et des cas d'usage différents.

De nombreux data scientists ont des difficultés avec l'efficacité du filtrage, en particulier lorsqu'ils travaillent avec de grands ensembles de données ou des conditions complexes. Utiliser la mauvaise méthode peut ralentir votre analyse de plusieurs ordres de grandeur. Comprendre quand utiliser l'indexation booléenne plutôt que .query() ou .loc[] peut faire la différence entre un script qui s'exécute en secondes et un qui prend des minutes.

Ce guide couvre toutes les méthodes de filtrage pandas avec des exemples pratiques, des comparaisons de performances et des meilleures pratiques. Vous apprendrez l'indexation booléenne, la méthode .query(), la sélection .loc[], la fonction .where() et la méthode .filter(). À la fin, vous saurez exactement quelle approche utiliser pour n'importe quel scénario de filtrage.

📚

Comprendre les Méthodes de Filtrage de Lignes Pandas

Pandas fournit cinq méthodes principales pour filtrer les lignes de DataFrame, chacune adaptée à différents scénarios :

MéthodeMeilleure PourExemple de SyntaxePerformance
Indexation BooléenneConditions simples, lisibilitédf[df['age'] > 25]Rapide pour données petites-moyennes
.query()Conditions complexes, basé sur chaînesdf.query('age > 25 and city == "NYC"')Plus rapide pour grandes données
.loc[]Basé sur étiquettes avec conditionsdf.loc[df['age'] > 25, ['name', 'age']]Sélection flexible de colonnes
.where()Conserver structure, remplacer valeursdf.where(df['age'] > 25, np.nan)Préserve forme du DataFrame
.filter()Filtrer par noms colonne/indexdf.filter(like='total', axis=1)Motifs noms colonne/index

Explorons chaque méthode avec des exemples détaillés.

Indexation Booléenne : L'Approche la Plus Courante

L'indexation booléenne filtre les lignes en créant un masque booléen (valeurs True/False) et en l'appliquant au DataFrame. C'est la méthode la plus intuitive pour les débutants.

import pandas as pd
import numpy as np
 
# Créer un DataFrame exemple
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
    'age': [25, 30, 35, 28, 32],
    'city': ['NYC', 'LA', 'NYC', 'Chicago', 'LA'],
    'salary': [70000, 80000, 90000, 75000, 85000]
})
 
# Filtrer les lignes où age est supérieur à 30
filtered = df[df['age'] > 30]
print(filtered)
#       name  age city  salary
# 2  Charlie   35  NYC   90000
# 4      Eve   32   LA   85000
 
# Voir le masque booléen
print(df['age'] > 30)
# 0    False
# 1    False
# 2     True
# 3    False
# 4     True

L'indexation booléenne fonctionne en évaluant la condition df['age'] > 30, qui renvoie une Series de valeurs True/False. Lorsque vous passez ce masque au DataFrame avec df[mask], pandas ne renvoie que les lignes où le masque est True.

Filtrer avec Plusieurs Conditions

Combinez plusieurs conditions en utilisant des opérateurs logiques. Important : Utilisez & (et), | (ou), ~ (non) au lieu des mots-clés and, or, not de Python. Enveloppez toujours chaque condition entre parenthèses.

# Plusieurs conditions avec AND
filtered = df[(df['age'] > 25) & (df['city'] == 'NYC')]
print(filtered)
#       name  age city  salary
# 2  Charlie   35  NYC   90000
 
# Plusieurs conditions avec OR
filtered = df[(df['age'] > 30) | (df['salary'] > 80000)]
print(filtered)
#       name  age     city  salary
# 2  Charlie   35      NYC   90000
# 4      Eve   32       LA   85000
 
# Opérateur NOT
filtered = df[~(df['city'] == 'NYC')]
print(filtered)
#     name  age     city  salary
# 1    Bob   30       LA   80000
# 3  David   28  Chicago   75000
# 4    Eve   32       LA   85000

Utiliser .isin() pour Plusieurs Valeurs

Filtrez les lignes où une colonne correspond à n'importe quelle valeur dans une liste en utilisant .isin() :

# Filtrer les lignes où city est NYC ou LA
cities = ['NYC', 'LA']
filtered = df[df['city'].isin(cities)]
print(filtered)
#       name  age city  salary
# 0    Alice   25  NYC   70000
# 1      Bob   30   LA   80000
# 2  Charlie   35  NYC   90000
# 4      Eve   32   LA   85000
 
# Inverse : villes PAS dans la liste
filtered = df[~df['city'].isin(cities)]
print(filtered)
#     name  age     city  salary
# 3  David   28  Chicago   75000

Filtrer avec .between()

La méthode .between() filtre les valeurs dans une plage (inclusive par défaut) :

# Filtrer les âges entre 28 et 32
filtered = df[df['age'].between(28, 32)]
print(filtered)
#     name  age     city  salary
# 1    Bob   30       LA   80000
# 3  David   28  Chicago   75000
# 4    Eve   32       LA   85000
 
# Limites exclusives
filtered = df[df['age'].between(28, 32, inclusive='neither')]
print(filtered)
#   name  age city  salary
# 1  Bob   30   LA   80000

La Méthode .query() : Filtrage Basé sur Chaînes

La méthode .query() accepte une expression de chaîne, la rendant lisible pour les conditions complexes. Elle est particulièrement efficace pour les grands DataFrames car elle utilise numexpr pour l'optimisation.

# Requête simple
filtered = df.query('age > 30')
print(filtered)
#       name  age city  salary
# 2  Charlie   35  NYC   90000
# 4      Eve   32   LA   85000
 
# Plusieurs conditions
filtered = df.query('age > 25 and city == "NYC"')
print(filtered)
#       name  age city  salary
# 2  Charlie   35  NYC   90000
 
# Utiliser des variables avec le symbole @
min_age = 30
filtered = df.query('age > @min_age')
print(filtered)
#       name  age city  salary
# 2  Charlie   35  NYC   90000
# 4      Eve   32   LA   85000

Expressions .query() Avancées

# Utiliser .isin() dans query
cities = ['NYC', 'LA']
filtered = df.query('city in @cities')
print(filtered)
 
# Conditions de plage
filtered = df.query('28 <= age <= 32')
print(filtered)
 
# Méthodes de chaîne
filtered = df.query('city.str.contains("LA")', engine='python')
print(filtered)

.loc[] pour le Filtrage Basé sur Étiquettes

L'indexeur .loc[] combine le filtrage de lignes avec la sélection de colonnes. Utilisez-le lorsque vous avez besoin de colonnes spécifiques à partir de lignes filtrées.

# Filtrer les lignes et sélectionner les colonnes
filtered = df.loc[df['age'] > 30, ['name', 'age']]
print(filtered)
#       name  age
# 2  Charlie   35
# 4      Eve   32
 
# Plusieurs conditions
filtered = df.loc[(df['age'] > 25) & (df['salary'] > 75000), ['name', 'salary']]
print(filtered)
#       name  salary
# 1      Bob   80000
# 2  Charlie   90000
# 4      Eve   85000
 
# Toutes les colonnes
filtered = df.loc[df['city'] == 'NYC', :]
print(filtered)

Méthode .where() : Remplacement Conditionnel de Valeurs

Contrairement aux autres méthodes, .where() préserve la forme du DataFrame en remplaçant les valeurs qui ne remplissent pas la condition par NaN (ou une valeur spécifiée).

# Conserver les valeurs où age > 30, remplacer les autres par NaN
result = df.where(df['age'] > 30)
print(result)
#       name   age city   salary
# 0      NaN   NaN  NaN      NaN
# 1      NaN   NaN  NaN      NaN
# 2  Charlie  35.0  NYC  90000.0
# 3      NaN   NaN  NaN      NaN
# 4      Eve  32.0   LA  85000.0
 
# Remplacer par une valeur personnalisée
result = df.where(df['age'] > 30, 'FILTERED')
print(result)
 
# Supprimer les lignes avec NaN après .where()
result = df.where(df['age'] > 30).dropna()
print(result)

Méthode .filter() : Filtrer par Noms de Colonne/Index

La méthode .filter() filtre les colonnes ou les lignes par leurs étiquettes (noms), pas par valeurs. Utilisez-la pour la sélection de colonnes basée sur des motifs.

# Créer un DataFrame avec plusieurs colonnes
df_wide = pd.DataFrame({
    'total_sales': [100, 200, 300],
    'total_profit': [20, 40, 60],
    'monthly_sales': [10, 20, 30],
    'yearly_sales': [120, 240, 360],
    'region': ['East', 'West', 'North']
})
 
# Filtrer les colonnes contenant 'total'
filtered = df_wide.filter(like='total')
print(filtered)
#    total_sales  total_profit
# 0          100            20
# 1          200            40
# 2          300            60
 
# Filtrer les colonnes en utilisant regex
filtered = df_wide.filter(regex=r'.*sales$')
print(filtered)
#    total_sales  monthly_sales  yearly_sales
# 0          100             10           120
# 1          200             20           240
# 2          300             30           360
 
# Filtrer les colonnes par noms exacts
filtered = df_wide.filter(items=['total_sales', 'region'])
print(filtered)

Filtrer les Données Chaînes

Pandas fournit des méthodes de chaînes via l'accesseur .str pour filtrer les colonnes de texte.

# Créer un DataFrame avec des données texte
df_text = pd.DataFrame({
    'name': ['Alice Smith', 'Bob Johnson', 'Charlie Brown', 'David Lee'],
    'email': ['alice@gmail.com', 'bob@yahoo.com', 'charlie@gmail.com', 'david@outlook.com']
})
 
# Filtrer les lignes où name contient 'Smith'
filtered = df_text[df_text['name'].str.contains('Smith')]
print(filtered)
#          name           email
# 0  Alice Smith  alice@gmail.com
 
# Recherche insensible à la casse
filtered = df_text[df_text['name'].str.contains('smith', case=False)]
print(filtered)
 
# Filtrer par domaine email
filtered = df_text[df_text['email'].str.endswith('gmail.com')]
print(filtered)
#            name              email
# 0   Alice Smith    alice@gmail.com
# 2  Charlie Brown  charlie@gmail.com
 
# Filtrer avec regex
filtered = df_text[df_text['name'].str.match(r'^[A-C]')]
print(filtered)

Filtrer les Valeurs Nulles et Non Nulles

Utilisez .isna(), .notna(), .isnull() et .notnull() pour filtrer en fonction des données manquantes.

# Créer un DataFrame avec des valeurs manquantes
df_missing = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, 7, 8],
    'C': [9, 10, 11, 12]
})
 
# Filtrer les lignes où la colonne A n'est pas null
filtered = df_missing[df_missing['A'].notna()]
print(filtered)
#      A    B   C
# 0  1.0  5.0   9
# 1  2.0  NaN  10
# 3  4.0  8.0  12
 
# Filtrer les lignes où N'IMPORTE QUELLE colonne est null
filtered = df_missing[df_missing.isna().any(axis=1)]
print(filtered)
#      A    B   C
# 1  2.0  NaN  10
# 2  NaN  7.0  11
 
# Filtrer les lignes où TOUTES les colonnes ne sont pas null
filtered = df_missing[df_missing.notna().all(axis=1)]
print(filtered)
#      A    B   C
# 0  1.0  5.0   9
# 3  4.0  8.0  12

Filtrer par Plages de Dates

Lorsque vous travaillez avec des colonnes datetime, vous pouvez filtrer par plages de dates en utilisant des opérateurs de comparaison standard.

# Créer un DataFrame avec des dates
df_dates = pd.DataFrame({
    'date': pd.date_range('2026-01-01', periods=10, freq='D'),
    'value': range(10)
})
 
# Filtrer les dates après une date spécifique
filtered = df_dates[df_dates['date'] > '2026-01-05']
print(filtered)
 
# Filtrer une plage de dates
start_date = '2026-01-03'
end_date = '2026-01-07'
filtered = df_dates[(df_dates['date'] >= start_date) & (df_dates['date'] <= end_date)]
print(filtered)
 
# Utiliser .between() pour les dates
filtered = df_dates[df_dates['date'].between('2026-01-03', '2026-01-07')]
print(filtered)

Comparaison de Performance : Grands DataFrames

Différentes méthodes de filtrage ont différentes caractéristiques de performance. Voici une comparaison pour un DataFrame avec 1 million de lignes :

import time
 
# Créer un grand DataFrame
np.random.seed(42)
df_large = pd.DataFrame({
    'A': np.random.randint(0, 100, 1000000),
    'B': np.random.randint(0, 100, 1000000),
    'C': np.random.choice(['X', 'Y', 'Z'], 1000000)
})
 
# Indexation booléenne
start = time.time()
result = df_large[(df_large['A'] > 50) & (df_large['B'] < 30)]
print(f"Indexation booléenne : {time.time() - start:.4f} secondes")
 
# Méthode .query()
start = time.time()
result = df_large.query('A > 50 and B < 30')
print(f"Méthode .query() : {time.time() - start:.4f} secondes")
 
# Méthode .loc[]
start = time.time()
result = df_large.loc[(df_large['A'] > 50) & (df_large['B'] < 30)]
print(f"Méthode .loc[] : {time.time() - start:.4f} secondes")

Informations sur les performances :

  • Indexation booléenne : Rapide pour les conditions simples, plus lente pour les filtres complexes à plusieurs conditions
  • .query() : Plus rapide pour les grands DataFrames avec plusieurs conditions (utilise l'optimisation numexpr)
  • .loc[] : Similaire à l'indexation booléenne mais plus flexible pour la sélection de colonnes
  • .where() : Plus lent en raison de la traversée complète du DataFrame, à utiliser uniquement lorsque vous devez préserver la forme

Pour les ensembles de données de plus de 100 000 lignes avec plusieurs conditions, .query() surpasse généralement l'indexation booléenne de 20 à 40 %.

Erreurs Courantes et Comment les Éviter

Erreur 1 : Utiliser 'and' au Lieu de '&'

# INCORRECT - lève ValueError
# filtered = df[df['age'] > 25 and df['city'] == 'NYC']
 
# CORRECT
filtered = df[(df['age'] > 25) & (df['city'] == 'NYC')]

Erreur 2 : Oublier les Parenthèses

# INCORRECT - problèmes de précédence d'opérateur
# filtered = df[df['age'] > 25 & df['city'] == 'NYC']
 
# CORRECT - envelopper chaque condition
filtered = df[(df['age'] > 25) & (df['city'] == 'NYC')]

Erreur 3 : Modifier le DataFrame Original

# Le filtrage crée une vue, pas une copie
filtered = df[df['age'] > 30]
 
# INCORRECT - SettingWithCopyWarning
# filtered['new_col'] = 100
 
# CORRECT - créer une copie explicite
filtered = df[df['age'] > 30].copy()
filtered['new_col'] = 100

Erreur 4 : Filtrage de Chaîne sans Gérer NaN

df_with_nan = pd.DataFrame({
    'name': ['Alice', np.nan, 'Charlie']
})
 
# INCORRECT - lève une erreur si NaN présent
# filtered = df_with_nan[df_with_nan['name'].str.contains('li')]
 
# CORRECT - gérer NaN avec le paramètre na
filtered = df_with_nan[df_with_nan['name'].str.contains('li', na=False)]

Visualiser les Données Filtrées avec PyGWalker

Après avoir filtré votre DataFrame pandas, visualiser les résultats aide à découvrir des motifs et des insights. PyGWalker (opens in a new tab) transforme les DataFrames filtrés en une interface interactive semblable à Tableau directement dans les notebooks Python, sans avoir besoin d'exporter des données ou d'écrire un code de traçage complexe.

PyGWalker est particulièrement utile lors de l'exploration d'ensembles de données filtrés car il vous permet de :

  • Glisser-déposer des colonnes pour créer des graphiques instantanément
  • Appliquer des filtres supplémentaires visuellement sans écrire de code
  • Basculer entre les types de graphiques (barres, lignes, nuages de points, carte thermique) en quelques secondes
  • Exporter des visualisations pour des rapports ou des présentations
import pygwalker as pyg
 
# Filtrer le DataFrame
filtered_df = df[(df['age'] > 25) & (df['salary'] > 75000)]
 
# Lancer la visualisation interactive
pyg.walk(filtered_df)

Cela ouvre une interface interactive où vous pouvez créer des visualisations en faisant glisser des colonnes filtrées dans le constructeur de graphiques. Pour les analystes de données travaillant avec plusieurs conditions de filtre, PyGWalker élimine le cycle d'itération de filtrer → tracer → ajuster → retracer.

FAQ

Comment filtrer les lignes de DataFrame pandas par condition ?

Utilisez l'indexation booléenne avec df[df['column'] > value] pour les conditions simples. Pour plusieurs conditions, utilisez & (et), | (ou), ~ (non) avec parenthèses : df[(df['A'] > 10) & (df['B'] < 20)]. Alternativement, utilisez .query() pour une syntaxe lisible : df.query('A > 10 and B < 20').

Quelle est la différence entre .loc[] et l'indexation booléenne ?

L'indexation booléenne (df[df['col'] > 5]) renvoie toutes les colonnes pour les lignes filtrées. .loc[] permet la sélection de colonnes simultanément : df.loc[df['col'] > 5, ['col1', 'col2']]. Les deux méthodes ont des performances similaires, mais .loc[] est plus explicite et prend en charge la sélection de lignes basée sur les étiquettes.

Comment filtrer un DataFrame pandas avec plusieurs conditions ?

Combinez les conditions en utilisant les opérateurs & (et), | (ou), ~ (non). Enveloppez toujours chaque condition entre parenthèses : df[(df['age'] > 25) & (df['city'] == 'NYC') | (df['salary'] > 80000)]. Pour les conditions complexes, utilisez .query() : df.query('age > 25 and (city == "NYC" or salary > 80000)').

Quand devrais-je utiliser .query() au lieu de l'indexation booléenne ?

Utilisez .query() pour les grands DataFrames (>100k lignes) avec plusieurs conditions : c'est 20 à 40 % plus rapide grâce à l'optimisation numexpr. C'est aussi plus lisible pour les conditions complexes. Utilisez l'indexation booléenne pour les filtres simples ou lorsque vous avez besoin d'une compatibilité maximale (.query() nécessite des expressions de chaîne plus difficiles à déboguer).

Comment filtrer les lignes où la valeur de colonne est dans une liste ?

Utilisez la méthode .isin() : df[df['city'].isin(['NYC', 'LA', 'Chicago'])]. Pour l'inverse (pas dans la liste), utilisez l'opérateur ~ : df[~df['city'].isin(['NYC', 'LA'])]. C'est plus efficace que d'enchaîner plusieurs conditions | pour de grandes listes.

Conclusion

Filtrer les lignes de DataFrame pandas est une compétence fondamentale pour l'analyse de données en Python. Vous comprenez maintenant cinq méthodes de filtrage : l'indexation booléenne pour la simplicité, .query() pour les performances, .loc[] pour la sélection flexible de colonnes, .where() pour le remplacement de valeurs et .filter() pour les motifs de noms de colonnes.

Points clés à retenir :

  • Utilisez l'indexation booléenne pour des filtres rapides et lisibles sur des ensembles de données petits à moyens
  • Choisissez .query() pour les grands ensembles de données avec des conditions complexes (20-40 % plus rapide)
  • Appliquez .loc[] lorsque vous avez besoin à la fois du filtrage de lignes et de la sélection de colonnes
  • N'oubliez pas d'utiliser les opérateurs &, |, ~ au lieu de and, or, not
  • Enveloppez toujours les conditions entre parenthèses pour éviter les problèmes de précédence d'opérateur

Maîtrisez ces techniques de filtrage et vous gérerez efficacement n'importe quel scénario de sélection de données. Pour l'exploration interactive de données filtrées, envisagez d'utiliser PyGWalker pour visualiser vos résultats sans écrire de code de traçage supplémentaire.

📚