Cours
Si vous utilisez régulièrement Python pour l’analyse de données, comme moi, vous constatez vite que la lecture de fichiers CSV fait partie des tâches les plus courantes. Mais à mesure que vos jeux de données grossissent, cette méthode peut devenir lente ou gourmande en mémoire.
Polars est une bibliothèque DataFrame rapide et moderne pour Python, conçue comme une alternative haute performance à Pandas. Elle gère les grands volumes de données avec beaucoup plus de fluidité, car elle est pensée pour la vitesse et une faible empreinte mémoire.
La fonction centrale pl.read_csv() de Polars offre un moyen simple de charger des fichiers CSV dans un DataFrame, avec des options intégrées pour contrôler l’analyse, les types de données et l’utilisation mémoire.
Dans ce guide, je vous montre comment lire des fichiers CSV, maîtriser l’analyse et traiter de grands jeux de données avec la fonction pl.read_csv() de Polars. Si vous débutez, découvrez notre cours Introduction to Polars pour apprendre à manipuler les données et en tirer des insights avec Polars.
Utilisation de base de pl.read_csv()
Avant d’aller plus loin, consultez notre tutoriel Python Polars pour configurer votre environnement.
Voyons maintenant comment fonctionne la fonction pl.read_csv() :
# import the module
import polars as pl
# Load CSV into a Polars DataFrame
fuel_data = pl.read_csv("Fuel_Consumption_2000-2022.csv")
# Preview first few rows
print(fuel_data.head())
Dans l’exemple ci-dessus, Polars lit le fichier et le charge dans un DataFrame. La fonction renvoie un DataFrame Polars, une structure tabulaire comparable à ce que vous obtiendriez avec pandas.
Par défaut, pl.read_csv() :
-
Considère que la première ligne contient les noms de colonnes (
has_header=True) -
Déduit automatiquement les types de données des colonnes
-
Utilise la virgule (
,) comme séparateur -
Charge l’intégralité du fichier en mémoire
Paramètres courants de pl.read_csv()
Maintenant que vous savez comment pl.read_csv() charge les données, voyons comment utiliser les paramètres suivants pour adapter la façon dont Polars analyse votre fichier.
Chemin de fichier et source
Polars vous permet de charger des données depuis différentes sources. Vous pouvez passer un chemin local (chaîne), un objet Pathlib ou même une URL. Par exemple, le code suivant lit un gros fichier CSV en ligne contenant le PIB de différents pays selon les années.
# Reading from a URL
url = "https://raw.githubusercontent.com/datasets/gdp/master/data/gdp.csv"
gdp_data = pl.read_csv(url)
Délimiteurs et séparateurs
Tous les fichiers CSV n’utilisent pas la virgule. Vous pouvez utiliser l’argument separator pour gérer les tabulations, points-virgules, pipes ou autres caractères. L’exemple ci-dessous montre comment spécifier les séparateurs à la lecture des fichiers.
# Reading a Semicolon-separated file
sales_data = pl.read_csv("2024_sales.csv", separator=";")
# Reading a Tab-separated file (TSV)
orders_data = pl.read_csv("all_orders.tsv", separator="\t")
Gestion de l’en-tête
Comme vu précédemment, Polars suppose que la première ligne contient les noms de colonnes. Si votre fichier n’a pas de ligne d’en-tête, utilisez le paramètre has_header=False comme ci-dessous. Polars attribuera automatiquement des noms comme column_1, column_2, column_3, etc.
# Load file without a header
orders_data = pl.read_csv("all_orders.csv", has_header=False)
Vous pouvez aussi renommer les colonnes en fournissant des noms précis. Par exemple :
# Providing specific column names
sales_data = pl.read_csv("sales_April.csv", new_columns=[
"OrderDate", "OrderNumber", "ProductKey", "SalespersonKey", "Salesperson"])
Encodage
Les fichiers CSV peuvent utiliser des encodages texte différents. Si vous rencontrez des caractères étranges ou des erreurs, précisez l’encodage :
# Load CSV into a Polars DataFrame
fuel_data = pl.read_csv("Fuel_Consumption_2000-2022.csv", encoding="utf8")
Parmi les autres options courantes, citons "latin1" et "utf8-lossy", qui gèrent correctement les caractères invalides.
Comment sélectionner des colonnes lors de la lecture d’un CSV avec Polars
Avec de gros fichiers CSV, vous n’avez souvent pas besoin de toutes les colonnes. Polars vous permet de ne charger que les colonnes requises via le paramètre columns.
# Load only specific columns
fuel_data = pl.read_csv("Fuel_Consumption_2000-2022.csv",
columns=["YEAR", "MAKE", "MODEL"]
)
Sélectionner les colonnes nécessaires dès le chargement réduit l’utilisation mémoire en évitant d’importer des données inutiles. Cette méthode accélère aussi la lecture et améliore les performances globales du pipeline.
Comment gérer les types de données (schéma) dans les CSV avec Polars
Polars est une bibliothèque fortement typée : chaque colonne doit avoir un type de données cohérent, par exemple uniquement des entiers ou uniquement des chaînes.
Inférence automatique des types
Par défaut, Polars inspecte vos données et détermine automatiquement les types des colonnes. Cette méthode fonctionne bien dans la plupart des cas, mais peut parfois se tromper, par exemple en traitant des identifiants comme des entiers au lieu de chaînes.
Définition manuelle du schéma
Si vous voulez garantir la cohérence de votre DataFrame, définissez le schéma manuellement. Cela assure l’homogénéité entre plusieurs fichiers et vous évite des erreurs de type en aval.
Dans la majorité des cas, utilisez schema_overrides pour préciser le type de certaines colonnes tout en laissant Polars déduire les autres.
import polars as pl
# Manually overriding specific data types
empl_data = pl.read_csv(
"all_employees.csv",
schema_overrides={
"id": pl.Int64,
"name": pl.String,
"age": pl.Int64,
"salary": pl.Float64
}
)
Ou utilisez schema pour définir toute la structure du DataFrame.
# Manually define the full schema
empl_data = pl.read_csv(
"all_employees.csv",
schema={
"id": pl.Int64,
"name": pl.String,
"age": pl.Int64,
"salary": pl.Float64
}
)
Comment gérer les valeurs manquantes dans les CSV avec Polars
Par défaut, Polars détecte automatiquement les valeurs manquantes et les représente par null. Parfois, ces valeurs manquantes sont codées par des chaînes spécifiques, comme "NA", "N/A" ou "missing". Vous pouvez les définir avec null_values pour qu’elles soient traitées comme null.
# Treating "N/A" and "EMPTY" as nulls
survey_data = pl.read_csv(
"survey_results.csv",
null_values=["N/A", "EMPTY", "null"]
)
Bien traiter les valeurs manquantes garantit des types cohérents et évite des calculs erronés, réduisant les erreurs lors de l’analyse et de la modélisation.
Lire de gros fichiers CSV avec Polars
Avec des jeux de données volumineux qui dépassent votre RAM disponible, Polars se distingue en traitant les données sans charger tout le fichier en une fois.
Chargement paresseux avec scan_csv()
Au lieu de charger immédiatement les données en mémoire comme read_csv(), Polars propose une alternative paresseuse, scan_csv(), qui construit un plan de requête optimisé et n’exécute que les opérations nécessaires.
Dans l’exemple ci-dessous, pl.scan_csv parcourt le fichier CSV sans le charger, construit une requête pour ne récupérer que les colonnes « YEAR », « MAKE » et « MODEL » où la marque est « ACURA », puis exécute cette requête. Seule la portion filtrée est alors chargée en mémoire, au lieu du fichier entier.
# Lazily reference the file (no data loaded yet)
fuel_consumption = pl.scan_csv("Fuel_Consumption_2000-2022.csv")
fuel_consumption_filtered = fuel_consumption.select(
["YEAR", "MAKE", "MODEL"]).filter(pl.col("MAKE") == "ACURA")
# Execute the query and load only the required data
fuel_consumption_acura = fuel_consumption_filtered.collect()
Je vous recommande d’utiliser scan_csv() lorsque :
- Vous travaillez avec des fichiers volumineux qui ne tiennent pas confortablement en mémoire
- Vous appliquez plusieurs transformations, comme filtrer, sélectionner et agréger
- Vous souhaitez une optimisation de la requête avant exécution
Streaming et efficacité mémoire
Polars permet aussi de traiter les données en flux, par morceaux, en maintenant un pic mémoire constant quelle que soit la taille du fichier.
Pour de gros fichiers CSV, commencez par scan_csv() pour créer une requête paresseuse. Le fichier n’est pas entièrement chargé à l’appel de scan_csv().
# Read data in chunks
fuel_consumption = pl.scan_csv("Fuel_Consumption_2000-2022.csv",
low_memory=True)
Comme la méthode ci-dessus utilise encore read_csv, la meilleure approche est de combiner exécution paresseuse et streaming.
Dans l’exemple suivant, Polars traite le fichier en pipeline, ligne par ligne par lots, en conservant en mémoire uniquement les lignes filtrées (où "CYLINDERS" > 3) à un instant donné.
# Lazily reference the file (no data loaded yet)
fuel_consumption = pl.scan_csv("Fuel_Consumption_2000-2022.csv")
result = fuel_consumption.filter(pl.col("CYLINDERS") > 3)
# Stream execution instead of loading everything at once
fuel_consumption_high = result.collect(engine="streaming")
Avantage de performance vs. Pandas
Comparé à pandas, Polars est souvent plus performant pour la lecture et le traitement de CSV, comme nous allons le voir dans la section suivante.
Polars read_csv vs Pandas read_csv
Le tableau ci-dessous résume les différences entre Polars et Pandas pour la lecture de CSV en Python.
|
Aspect |
Polars |
Pandas |
|
Vitesse |
Plus rapide grâce au multithreading et à un parsing optimisé |
Plus lent sur les gros fichiers (principalement monothread) |
|
Utilisation mémoire |
Empreinte plus faible ; prise en charge du lazy + streaming |
Charge l’ensemble du jeu de données directement en mémoire |
|
Syntaxe |
|
|
|
Modèle d’exécution |
Prend en charge l’exécution paresseuse ( |
Exécution immédiate uniquement |
|
Optimisation |
Optimisation de requête intégrée (projection, filtrage) |
Optimisation automatique limitée |
|
Meilleur cas d’usage |
Grands jeux de données, workflows critiques en performance |
Jeux de données plus petits, analyses rapides |
Je vous recommande de lire notre article sur les différences entre Pandas et Polars pour déterminer quel outil correspond le mieux à vos besoins analytiques.
Lire un CSV depuis différentes sources
Comme nous l’avons vu, vous pouvez utiliser Polars pour lire des fichiers CSV provenant de différentes sources. Dans les exemples ci-dessus, je vous ai montré comment lire un CSV depuis des fichiers locaux et des URL.
De plus, Polars gère automatiquement les fichiers CSV compressés. Par exemple, le code suivant lit des données depuis un fichier .gzip.
# Read gzip-compressed CSV
census_data = pl.read_csv("2018_census.csv.gz")
Erreurs courantes et dépannage
Même avec un moteur haute performance comme Polars, vous pouvez rencontrer des problèmes, notamment lors de la lecture d’un CSV. Voici quelques difficultés fréquentes que j’ai rencontrées et comment les résoudre.
-
Erreurs d’encodage : vous pouvez voir une erreur de type
UnicodeDecodeError, ce qui signifie que le fichier n’est pas en UTF-8, un problème courant avec d’anciens fichiers ou des CSV exportés depuis certaines versions d’Excel. Pour corriger cela, définissez l’encodage approprié ou utilisez"utf8-lossy"si le fichier contient des caractères incohérents ou corrompus. -
Problèmes de séparateur : si votre DataFrame se charge mais que toutes les données sont agglutinées dans une seule colonne, Polars n’a pas reconnu le séparateur. Pour résoudre ce problème, définissez explicitement le bon séparateur via l’argument
separator, par exemple point-virgule (;), tabulation (\t) ou pipe (|). -
Types de données incorrects : il arrive que Polars infère mal certains types, par exemple en lisant des identifiants numériques comme des chaînes ou en rencontrant des erreurs de parsing. Dans ce cas, utilisez
schema_overridespour définir le type de colonnes spécifiques. Si vous voulez définir les types de chaque colonne, utilisezschema. Vous pouvez aussi augmenterinfer_schema_lengthpour que Polars examine plus de lignes avant d’inférer le schéma. -
Problèmes mémoire avec de gros fichiers : si votre processus Python plante lors du chargement d’un gros fichier, c’est que votre RAM est saturée. Passez de
read_csv()àscan_csv()pour un chargement paresseux, réduire l’empreinte mémoire et améliorer les performances. Vous pouvez aussi ne charger qu’une partie des colonnes ou utiliser l’exécution en streaming pour traiter les données par blocs.
Conclusion
La fonction read_csv() de Polars est simple d’emploi, mais suffisamment puissante pour des cas d’usage concrets. À mon avis, Polars prend l’avantage dès que les jeux de données grossissent.
Pour aller plus loin, consultez notre blog sur le moteur GPU de Polars pour découvrir ses différents cas d’usage. Prêt à passer à la pratique ? Notre code-along Super Bowl Analytics with Polars vous guide pour résoudre des questions analytiques réelles, effectuer des calculs et appliquer des techniques de ML de base à des problématiques de sport.
FAQs
Quelle est la différence entre read_csv() et scan_csv() dans Polars ?
read_csv() charge les données immédiatement en mémoire, tandis que scan_csv() utilise l’exécution paresseuse et ne traite les données qu’à l’appel de .collect().
Quand dois-je utiliser scan_csv() plutôt que read_csv() ?
Utilisez scan_csv() pour les grands jeux de données ou lorsque vous enchaînez des transformations, car il optimise l’exécution et réduit l’utilisation mémoire.
Polars peut-il lire uniquement certaines colonnes d’un fichier CSV ?
Oui, utilisez le paramètre columns=[...] dans read_csv() ou sélectionnez les colonnes dans une requête paresseuse avec scan_csv().
Comment gérer les valeurs manquantes dans les fichiers CSV avec Polars ?
Polars traite par défaut les valeurs vides comme null, et vous pouvez définir des marqueurs personnalisés avec null_values=.
Polars prend-il en charge les fichiers CSV compressés ?
Oui, Polars peut lire des formats compressés comme .gz et .zip sans extraction manuelle.
