pandas concat - Maîtrisez l'assemblage de DataFrames

Xavier Moreau .

11 mai 2026

Exemple de `dataframe concat` avec Pandas, joignant deux dataframes sur l'axe 1 pour combiner leurs colonnes.

Assembler plusieurs DataFrames en un seul objet propre paraît simple, mais c’est souvent là que se cachent les problèmes d’index, de colonnes manquantes et de performance. Dans la logique de dataframe concat, l’enjeu n’est pas seulement de “coller” des blocs de données : il faut savoir quand empiler des lignes, quand aligner des colonnes et comment garder un schéma exploitable. Je vais aller droit au but avec les paramètres qui comptent, les pièges que je vois le plus souvent et les cas où `merge` ou `join` font mieux le travail.

Les points à garder en tête avant d’assembler les tables

  • `concat(..., axis=0)` empile des lignes ; `axis=1` aligne des colonnes sur l’index.
  • `ignore_index=True` est utile quand l’ancien index n’a plus de valeur métier.
  • `join="outer"` conserve tout ; `join="inner"` ne garde que les colonnes communes.
  • `keys` ajoute une provenance claire et construit un index hiérarchique si besoin.
  • Si la relation entre données est métier, `merge` ou `join` est souvent plus juste que `concat`.

Pourquoi concat est souvent le bon réflexe

Je vois `concat` comme un outil de composition structurelle. On l’utilise quand les blocs de données sont déjà compatibles et qu’il suffit de les réunir sans logique de correspondance métier. C’est typiquement le cas pour des lots mensuels, des exports successifs, des pages d’API ou des journaux applicatifs découpés en fragments.

La documentation pandas recommande d’ailleurs de préparer les morceaux dans une liste puis de faire une seule concaténation, plutôt que d’ajouter des lignes une par une. En pratique, c’est plus lisible et nettement plus efficace qu’une construction incrémentale qui reconstruit l’objet à chaque tour de boucle.

import pandas as pd

frames = [df_jan, df_fev, df_mar]
result = pd.concat(frames, ignore_index=True)

Ce point est important : `concat` ne modifie pas les objets d’entrée, il renvoie un nouvel objet. Je préfère donc penser en termes de blocs à assembler plutôt qu’en termes d’objet à enrichir petit à petit. Une fois ce cadre posé, le vrai choix devient l’axe de concaténation, et c’est lui qui change le sens de l’opération.

Exemple de `dataframe concat` avec Pandas, joignant deux dataframes sur l'axe 1 pour combiner leurs colonnes.

Empiler des lignes ou aligner des colonnes

Le paramètre `axis` est celui qui détermine le plus visiblement le résultat. Par défaut, `axis=0` empile les objets les uns sous les autres. Avec `axis=1`, on juxtapose des colonnes, en conservant l’alignement par index. C’est le bon endroit pour éviter les malentendus entre “ajouter des lignes” et “fusionner des données de contexte”.

Configuration Effet Cas d’usage typique Risque principal
`axis=0` Empile les lignes Exports successifs, lots de traitement, logs, données batch Index dupliqués si on conserve les labels d’origine
`axis=1` Aligne les colonnes sur l’index Enrichissement d’un même jeu de lignes avec des features ou des métadonnées Valeurs manquantes si les index ne correspondent pas

Quand je combine des lignes, j’utilise souvent `ignore_index=True` si l’index précédent n’a aucune signification métier. Quand je combine des colonnes, je vérifie d’abord que l’index représente bien la même entité des deux côtés, sinon le résultat peut sembler correct tout en étant faux.

# Empiler des lignes
result_rows = pd.concat([df_a, df_b], axis=0, ignore_index=True)

# Aligner des colonnes
result_cols = pd.concat([df_base, df_meta], axis=1)

Une fois l’axe choisi, les autres paramètres deviennent des réglages fins qui servent surtout à sécuriser le résultat ou à le rendre plus lisible.

Les paramètres qui changent vraiment le résultat

La plupart des bugs que je rencontre viennent moins de `concat` lui-même que d’un mauvais réglage de ses options. Les six paramètres ci-dessous couvrent l’essentiel des cas concrets en production.

Paramètre Ce qu’il change Quand je le choisis Vigilance
`ignore_index` Renumérote l’axe concaténé de `0` à `n-1` Quand l’index d’origine n’a pas de valeur métier Ne touche pas aux autres axes
`join` `outer` garde l’union, `inner` garde l’intersection Quand les schémas varient d’une source à l’autre `inner` peut supprimer des colonnes utiles sans bruit
`keys` Ajoute une provenance et crée un index hiérarchique Quand je veux savoir d’où vient chaque bloc Peut surprendre si on attend un index plat
`names` Nomme les niveaux d’index créés par `keys` Quand la lisibilité du MultiIndex compte Utile surtout si plusieurs lots sont empilés
`verify_integrity` Vérifie les doublons sur l’axe concaténé Quand un doublon d’index serait une erreur critique La vérification peut coûter cher sur de gros volumes
`sort` Trie l’axe non concaténé Quand l’ordre des colonnes doit être stabilisé Je le laisse généralement à `False` pour préserver l’ordre choisi
`copy` Plus d’effet utile dans les pandas récents Je ne le règle plus pour piloter le comportement Dans pandas récent, ce paramètre est ignoré

Le cas `keys` est particulièrement utile en ETL : il permet de conserver la provenance sans ajouter une colonne manuelle. La documentation pandas rappelle aussi que `copy` n’a plus d’impact dans les versions récentes, ce qui évite de s’accrocher à un faux levier de performance. Une fois ces réglages en tête, le plus important devient la préparation des objets avant l’assemblage.

Préparer les données avant de concaténer

Je préfère toujours normaliser les blocs avant de les combiner. Dans un pipeline backend ou dans un traitement d’analytics, cela veut dire harmoniser les noms de colonnes, convertir les types, sélectionner les champs utiles et seulement ensuite empiler les morceaux. Cette discipline évite les `NaN` surprenants, les colonnes en trop et les dtypes incohérents.

  1. Je renomme les colonnes pour obtenir un schéma commun.
  2. Je convertis les dates, les nombres et les identifiants dans le bon type.
  3. Je garde les blocs dans une liste Python, pas dans un DataFrame intermédiaire.
  4. Je fais une seule concaténation à la fin.
frames = []

for source in sources:
    df = pd.read_csv(source)
    df = df.rename(columns={"userId": "user_id"})
    df["created_at"] = pd.to_datetime(df["created_at"], errors="coerce")
    df = df[["user_id", "email", "created_at"]]
    frames.append(df)

result = pd.concat(frames, ignore_index=True)

Si je dois garder la trace de chaque source, j’ajoute volontiers `keys` au lieu d’injecter une colonne artificielle. C’est plus propre quand on veut auditer l’origine des lots plus tard. Une fois le pipeline propre, il reste à vérifier si `concat` est vraiment l’outil adapté, ou si une jointure métier serait plus juste.

Quand concat ne remplace pas merge

Je vois souvent `concat` utilisé à la place de `merge`, alors que les deux résolvent des problèmes différents. `concat` assemble des blocs compatibles le long d’un axe. `merge` fait une jointure sur des clés. `join`, lui, est très pratique pour raccorder des DataFrames par l’index, surtout quand l’index porte déjà la bonne sémantique.

Outil Logique Quand je l’utilise Point d’attention
`concat` Assemblage vertical ou horizontal sans correspondance métier Lignes de plusieurs lots, colonnes déjà alignées Ne fait pas de rapprochement intelligent sur des clés
`merge` Jointure de type SQL sur des colonnes ou des index Client, commande, identifiant d’utilisateur, référentiel métier Le choix des clés influence directement la qualité du résultat
`join` Raccordement orienté index, souvent sur les colonnes Quand l’index représente déjà l’entité à relier Moins explicite si les clés sont dans des colonnes normales

Si je dois enrichir des lignes avec un `customer_id`, je pense d’abord à `merge`. Si je dois simplement empiler des exportations journalières, `concat` est le bon choix. Cette distinction paraît évidente quand on la formule ainsi, mais elle fait gagner beaucoup de temps sur des projets où les données viennent de plusieurs services ou de plusieurs API.

Les erreurs que je surveille en priorité

Les résultats “qui ont l’air bons” sont souvent les plus dangereux. Je vérifie donc systématiquement quelques points avant de considérer une concaténation comme propre. C’est particulièrement vrai dans un flux d’intégration où les données arrivent depuis plusieurs systèmes et ne respectent pas exactement le même schéma.

Colonnes absentes et valeurs manquantes

Avec `join="outer"`, pandas conserve toutes les colonnes présentes dans les blocs d’entrée. C’est pratique, mais cela remplit aussi les trous avec des valeurs manquantes. Si une source perd une colonne ou si un export change de structure, le résultat peut sembler valide tout en introduisant des `NaN` partout. Dans ce cas, je préfère souvent normaliser les colonnes en amont plutôt que de masquer le problème par un assemblage trop permissif.

Indices dupliqués et provenance floue

Quand on garde l’index d’origine, les doublons sont fréquents. Ce n’est pas forcément un bug, mais c’est souvent une source d’ambiguïté dans les sélections et dans les jointures suivantes. Si l’index n’a pas de valeur métier, `ignore_index=True` simplifie beaucoup la suite. Si, au contraire, les doublons doivent être interdits, j’active `verify_integrity=True` pour les détecter tôt.

Concaténer dans une boucle

C’est l’erreur la plus classique. Ajouter un DataFrame à un autre à chaque itération finit par coûter nettement plus cher qu’une collecte en liste suivie d’une seule concaténation. Je ne garde la version incrémentale que pour des cas marginaux ; dans un vrai pipeline, je rassemble les morceaux d’abord, je combine ensuite.

Lire aussi : Meilleur IDE 2026 - Lequel choisir pour votre projet ?

Schémas trop différents

Si les blocs n’ont pas la même structure, il faut décider ce qu’on accepte de perdre. `join="inner"` est utile quand seules les colonnes communes comptent. `join="outer"` est plus souple, mais il peut produire un tableau très large et rempli de valeurs manquantes. Dans un projet solide, je préfère toujours rendre ce choix explicite avant l’exécution, plutôt que de le découvrir après coup dans un notebook ou dans un job planifié.

Avec ces pièges en tête, la meilleure approche consiste souvent à s’imposer une petite checklist avant d’envoyer le traitement en production.

Ce que je verrouille avant de l’utiliser en production

  • Je confirme si l’opération consiste à empiler des lignes ou à aligner des colonnes.
  • Je décide si l’index doit survivre ou s’il doit être reconstruit.
  • Je normalise les noms de colonnes et les types avant de réunir les blocs.
  • Je garde la provenance avec `keys` quand plusieurs sources cohabitent.
  • Je choisis volontairement entre `outer` et `inner`, au lieu de laisser le défaut décider à ma place.
  • Je teste les cas avec colonnes manquantes, index dupliqués et lots hétérogènes.

Au fond, je traite `concat` comme un outil de structure, pas comme un substitut universel aux jointures. Dès que l’opération consiste seulement à réunir des morceaux compatibles, je l’utilise sans hésiter ; dès qu’il faut faire correspondre des clés métier, je passe à `merge` ou `join`. Cette séparation simple me donne des pipelines plus lisibles, moins fragiles et beaucoup plus faciles à tester.

Questions fréquentes

`pd.concat` est idéal pour assembler des blocs de données compatibles (empiler des lignes, aligner des colonnes) sans logique de correspondance métier. Utilisez `pd.merge` pour des jointures basées sur des clés (comme SQL) et `pd.join` pour des fusions basées sur l'index.
Le paramètre `axis` détermine comment les DataFrames sont combinés. `axis=0` (par défaut) empile les lignes, ajoutant des observations. `axis=1` aligne les colonnes, ajoutant des variables ou des caractéristiques pour les mêmes entités basées sur l'index.
`ignore_index=True` crée un nouvel index numérique de 0 à n-1 pour le DataFrame résultant. C'est utile quand les index d'origine n'ont pas de signification métier et évite les index dupliqués, simplifiant les opérations ultérieures et améliorant la lisibilité.
La meilleure pratique est de collecter tous les DataFrames à concaténer dans une liste Python, puis d'effectuer une seule opération `pd.concat` à la fin. Évitez de concaténer dans une boucle, car cela recrée l'objet à chaque itération, ce qui est très inefficace.
Les pièges incluent les colonnes absentes (introduisant des NaN), les index dupliqués (si `ignore_index` n'est pas utilisé), la concaténation dans une boucle (problèmes de performance) et des schémas trop différents entre les DataFrames, nécessitant une gestion attentive du paramètre `join`.

Évaluer l'article

Moyenne: 0.0 / 5 · 0 évaluations

Tags

dataframe concat pandas concat plusieurs dataframes concaténer dataframes python pandas concat axis 0 vs axis 1
Autor Xavier Moreau
Xavier Moreau
Je m'appelle Xavier Moreau et je cumule 14 ans d'expérience dans le développement web, avec un accent particulier sur JavaScript, le backend, le NoSQL et la sécurité. Mon intérêt pour ces domaines a émergé dès mes débuts dans la programmation, où j'ai découvert la puissance des technologies web et leur capacité à transformer des idées en réalité. J'aime expliquer des concepts complexes de manière accessible, en aidant les lecteurs à naviguer dans les défis techniques qu'ils rencontrent. Au fil des ans, j'ai développé une expertise solide en vérifiant mes sources, en comparant les informations et en simplifiant des sujets parfois ardus. Je m'efforce toujours de fournir des contenus utiles, précis et à jour, en suivant les tendances du secteur et en organisant mes connaissances de manière claire. Mon objectif est d'accompagner les passionnés et les professionnels du développement web dans leur quête de compréhension et d'innovation.

Commentaires (0)

Ajouter un commentaire