Narwhals : écrivez votre code DataFrame une fois et exécutez-le sur pandas, Polars et PyArrow
Ce qu'est Narwhals — la couche de compatibilité légère qui vous laisse écrire la logique DataFrame une seule fois (API façon Polars) et l'exécuter sur pandas, Polars, PyArrow et plus, sans lock-in ni dépendances obligatoires.
Quiconque travaille avec des données en Python depuis un moment a déjà vécu ceci : un projet s'est standardisé sur pandas, un autre est passé à Polars pour la performance, un troisième consomme des données via PyArrow. Puis vous avez besoin d'une fonction de nettoyage — trimmer des chaînes, filtrer des lignes invalides, agréger par clé — et vous découvrez que l'API de chaque bibliothèque est assez différente pour que vous écriviez la même transformation deux ou trois fois.
Pire encore quand vous maintenez une bibliothèque interne réutilisée par plusieurs équipes : si elle dépend de pandas, vous imposez pandas à tout le monde ; si elle dépend de Polars, vous imposez Polars. Il n'existe pas de juste milieu élégant — jusqu'à ce que vous découvriez Narwhals.
Ce qu'est Narwhals
Narwhals est une couche de compatibilité légère et extensible entre bibliothèques de DataFrame. L'idée centrale est simple : vous écrivez la logique une seule fois, avec une API façon Polars (expressions, nw.col(...), méthodes chaînées), et Narwhals la traduit en opérations natives du backend que vous passez — pandas, Polars, PyArrow, Modin, Dask ou cuDF (GPU).
Deux principes de conception rendent la bibliothèque particulièrement utile pour l'ingénierie des données :
- Agnostique au backend avec un retour fidèle au type. Si vous avez passé un DataFrame pandas, vous récupérez du pandas. Si vous avez passé du Polars, vous récupérez du Polars. La bibliothèque ne vous pousse pas vers un format unique.
- Zéro dépendance obligatoire. Narwhals importe paresseusement le backend qu'il trouve au point d'appel. Un projet qui embarque Narwhals ne tire pas pandas, Polars ou PyArrow à moins que l'un d'eux ne soit déjà installé. Cela garde votre arbre de dépendances léger.
Le pattern d'usage en 3 étapes
Le flux canonique de Narwhals suit toujours la même forme :
import narwhals as nw
def nettoie(df):
# 1) Enveloppe n'importe quel DataFrame natif dans un objet Narwhals
df = nw.from_native(df)
# 2) Écrit la logique avec l'API Narwhals (façon Polars)
out = (
df.filter(nw.col("valeur") > 0)
.with_columns(nw.col("nom").str.to_uppercase())
)
# 3) Renvoie le type natif d'origine (pandas -> pandas, etc.)
return out.to_native()
La même fonction nettoie() fonctionne désormais avec n'importe lequel de ceux-ci :
import pandas as pd
import polars as pl
import pyarrow as pa
nettoie(pd.read_parquet("ventes.parquet")) # renvoie pandas.DataFrame
nettoie(pl.read_parquet("ventes.parquet")) # renvoie polars.DataFrame
nettoie(pa.parquet.read_table("ventes.parquet")) # renvoie pyarrow.Table
Pas une seule ligne de logique ne change entre les trois cas. C'est ça, le gain.
Un exemple un peu plus réel : l'agrégation
Un group_by s'écrit aussi une seule fois :
import narwhals as nw
@nw.narwhalify # décorateur : fait from_native/to_native automatiquement
def ca_par_region(df):
return (
df.group_by("region")
.agg(nw.col("valeur").sum().alias("ca"))
.sort("ca", descending=True)
)
Le décorateur @nw.narwhalify vous dispense d'appeler from_native/to_native à la main — il enveloppe les arguments d'entrée et déballe la sortie pour vous.
Pourquoi c'est important en pratique
- Moins de code à maintenir. Une base de transformations au lieu d'une par bibliothèque. Pour les équipes qui maintiennent des utilitaires internes, c'est la différence entre maintenir un code ou en maintenir cinq.
- Pas de lock-in de bibliothèque. Vous pouvez commencer sur pandas et migrer les parties critiques vers Polars sans réécrire la logique métier — vous changez juste le DataFrame d'entrée.
- Surcharge minimale. Narwhals est essentiellement une fine traduction vers l'API native ; il ne réimplémente pas le moteur d'exécution. Vous gardez la performance du backend choisi (Polars reste rapide, cuDF reste sur le GPU).
- Ce n'est pas un pari risqué. Des outils largement utilisés ont déjà adopté Narwhals en interne pour accepter n'importe quel DataFrame sans forcer une conversion vers pandas : Plotly Express, Altair, scikit-learn, marimo, shiny et Hugging Face
datasets. Quand des bibliothèques de cette taille misent sur une couche de compatibilité, c'est le signe que le problème est réel et la solution solide.
Quand (ne pas) l'utiliser
Narwhals est, par conception, un outil destiné à ceux qui construisent des outils — auteurs de bibliothèques et ingénieurs qui écrivent des utilitaires réutilisés par plusieurs projets ou plusieurs backends. Si votre projet est une application unique déjà standardisée sur Polars et qui ne quittera jamais Polars, écrire directement dans l'API Polars est parfaitement adéquat — vous ne gagnez pas grand-chose à ajouter une couche.
La valeur apparaît quand l'entrée est incertaine ou plurielle : une fonction publique qui peut recevoir pandas ou Polars, un pipeline qui consomme de sources différentes, une bibliothèque interne qui ne veut pas imposer un backend à ses consommateurs. Dans ces scénarios, Narwhals rembourse largement son coût.
Comment commencer
pip install narwhals
# ou, si vous utilisez uv :
uv add narwhals
Sans dépendances supplémentaires : installez seulement les backends que vous utilisez déjà. La documentation officielle propose le guide de démarrage rapide et la liste complète des opérations prises en charge.
Articles liés
ai_parse_document() : transformez un PDF en table gouvernée avec une seule instruction SQL
Comment ai_parse_document() de Databricks réunit OCR, parsing et reconstruction de tables en une seule instruction SQL — en livrant le résultat comme table gouvernée dans Unity Catalog.
Lire l'articleExpectations dans Lakeflow : la qualité des données comme code, gouvernée dans Unity Catalog
Comment déclarer des règles de qualité à côté de la transformation, choisir entre journaliser, écarter ou échouer, et tout gouverner via Unity Catalog avec des règles versionnées et auditables.
Lire l'articleVous avez aimé ? Découvrez les e-books pour du contenu approfondi.
E-books