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éthode | Meilleure Pour | Exemple de Syntaxe | Performance |
|---|---|---|---|
| Indexation Booléenne | Conditions simples, lisibilité | df[df['age'] > 25] | Rapide pour données petites-moyennes |
.query() | Conditions complexes, basé sur chaînes | df.query('age > 25 and city == "NYC"') | Plus rapide pour grandes données |
.loc[] | Basé sur étiquettes avec conditions | df.loc[df['age'] > 25, ['name', 'age']] | Sélection flexible de colonnes |
.where() | Conserver structure, remplacer valeurs | df.where(df['age'] > 25, np.nan) | Préserve forme du DataFrame |
.filter() | Filtrer par noms colonne/index | df.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 TrueL'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 85000Utiliser .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 75000Filtrer 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 80000La 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 85000Expressions .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 12Filtrer 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'] = 100Erreur 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 deand,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.