Pandas Concat : Comment concaténer des DataFrames en Python
Updated on
Les données du monde réel se trouvent rarement dans un seul fichier. Vous récupérez les ventes de janvier d'un CSV, celles de février d'un autre et les objectifs du T1 d'un troisième. Vous scrapez plusieurs pages web dans des DataFrames séparés. Vous divisez un grand jeu de données pour un traitement parallèle et devez réassembler les morceaux. Dans chaque cas, vous avez besoin d'un moyen fiable de combiner des DataFrames sans perdre de lignes, mélanger les colonnes ou corrompre votre index.
La fonction pandas concat (pd.concat()) est l'outil standard pour cette tâche. Elle empile les DataFrames verticalement (ajout de lignes) ou horizontalement (ajout de colonnes), gère élégamment les colonnes différentes et s'adapte à n'importe quel nombre de DataFrames en un seul appel. Ce guide couvre chaque paramètre dont vous avez besoin, avec des exemples de code fonctionnels que vous pouvez coller directement dans votre notebook.
Ce que fait pd.concat() -- Syntaxe de base
pd.concat() prend une liste (ou un dictionnaire) de DataFrames et les assemble le long d'un axe spécifié. Pensez-y comme empiler des blocs de construction -- verticalement pour ajouter plus de lignes, ou côte à côte pour ajouter plus de colonnes.
import pandas as pd
result = pd.concat(
objs, # list or dict of DataFrames
axis=0, # 0 = vertical (rows), 1 = horizontal (columns)
join='outer', # 'outer' or 'inner'
ignore_index=False,
keys=None,
sort=False,
verify_integrity=False
)Paramètres clés en un coup d'oeil
| Paramètre | Description | Défaut |
|---|---|---|
objs | Une liste ou un dictionnaire de DataFrames (ou Series) à concaténer | Requis |
axis | 0 pour empiler les lignes (vertical), 1 pour empiler les colonnes (horizontal) | 0 |
join | 'outer' conserve toutes les colonnes ; 'inner' conserve uniquement les colonnes communes | 'outer' |
ignore_index | Si True, réinitialise l'index à 0, 1, 2, ... dans le résultat | False |
keys | Étiquettes pour identifier de quel DataFrame original provient chaque ligne | None |
sort | Trier l'axe de non-concaténation (noms de colonnes pour axis=0) | False |
verify_integrity | Lever une erreur si le résultat a des valeurs d'index en double | False |
Données d'exemple pour tous les exemples
Chaque exemple ci-dessous utilise ces DataFrames :
import pandas as pd
df_jan = pd.DataFrame({
'product': ['Widget', 'Gadget', 'Sprocket'],
'units_sold': [150, 200, 80],
'revenue': [1500, 3000, 960]
})
df_feb = pd.DataFrame({
'product': ['Widget', 'Gadget', 'Sprocket'],
'units_sold': [170, 180, 95],
'revenue': [1700, 2700, 1140]
})
print(df_jan)
print(df_feb)Sortie :
product units_sold revenue
0 Widget 150 1500
1 Gadget 200 3000
2 Sprocket 80 960
product units_sold revenue
0 Widget 170 1700
1 Gadget 180 2700
2 Sprocket 95 1140Concaténer des DataFrames verticalement (axis=0)
La concaténation verticale est le cas d'utilisation le plus courant. Elle empile un DataFrame au-dessus d'un autre, ajoutant des lignes. C'est ce que vous utilisez lorsque vous avez des fichiers mensuels, des résultats par lots ou des données réparties sur plusieurs tables avec les mêmes colonnes.
combined = pd.concat([df_jan, df_feb])
print(combined)Sortie :
product units_sold revenue
0 Widget 150 1500
1 Gadget 200 3000
2 Sprocket 80 960
0 Widget 170 1700
1 Gadget 180 2700
2 Sprocket 95 1140Remarquez l'index : les deux DataFrames ont conservé leurs valeurs d'index originales (0, 1, 2), donc le résultat a des valeurs d'index en double. Ce n'est généralement pas ce que vous voulez. La solution est le paramètre ignore_index, couvert ensuite.
Le paramètre ignore_index -- Réinitialiser l'index
Définir ignore_index=True supprime l'index original et attribue un nouvel index séquentiel à partir de 0 :
combined = pd.concat([df_jan, df_feb], ignore_index=True)
print(combined)Sortie :
product units_sold revenue
0 Widget 150 1500
1 Gadget 200 3000
2 Sprocket 80 960
3 Widget 170 1700
4 Gadget 180 2700
5 Sprocket 95 1140Quand l'utiliser : Presque toujours lors d'une concaténation verticale. À moins que votre index ne contienne des informations significatives (comme des horodatages ou des identifiants uniques), réinitialisez-le pour éviter toute confusion ultérieure.
Le paramètre keys -- Créer un index hiérarchique
Le paramètre keys ajoute un niveau à l'index qui identifie la source de chaque ligne. Cela crée un MultiIndex (index hiérarchique) :
combined = pd.concat([df_jan, df_feb], keys=['January', 'February'])
print(combined)Sortie :
product units_sold revenue
January 0 Widget 150 1500
1 Gadget 200 3000
2 Sprocket 80 960
February 0 Widget 170 1700
1 Gadget 180 2700
2 Sprocket 95 1140Vous pouvez ensuite sélectionner les données d'une source spécifique avec .loc :
# Get only January data
jan_data = combined.loc['January']
print(jan_data)Sortie :
product units_sold revenue
0 Widget 150 1500
1 Gadget 200 3000
2 Sprocket 80 960Quand l'utiliser : Utilisez keys lorsque vous devez suivre de quel DataFrame original chaque ligne provient -- par exemple, des données provenant de différentes expériences, périodes ou sources de données.
Concaténer horizontalement (axis=1) -- Côte à côte
Définir axis=1 place les DataFrames côte à côte, ajoutant des colonnes. Pandas aligne les lignes par leurs valeurs d'index.
targets = pd.DataFrame({
'target_units': [160, 190, 90],
'target_revenue': [1600, 2850, 1080]
})
result = pd.concat([df_jan, targets], axis=1)
print(result)Sortie :
product units_sold revenue target_units target_revenue
0 Widget 150 1500 160 1600
1 Gadget 200 3000 190 2850
2 Sprocket 80 960 90 1080Cela fonctionne correctement car les deux DataFrames partagent le même index (0, 1, 2). Si les index ne sont pas alignés, vous obtenez des valeurs NaN pour les lignes qui ne correspondent pas :
df_a = pd.DataFrame({'value_a': [10, 20, 30]}, index=[0, 1, 2])
df_b = pd.DataFrame({'value_b': [40, 50, 60]}, index=[1, 2, 3])
result = pd.concat([df_a, df_b], axis=1)
print(result)Sortie :
value_a value_b
0 10.0 NaN
1 20.0 40.0
2 30.0 50.0
3 NaN 60.0La ligne 0 n'a pas de value_b (pas d'index correspondant dans df_b), et la ligne 3 n'a pas de value_a (pas d'index correspondant dans df_a).
Le paramètre join -- Inner vs Outer
Le paramètre join contrôle ce qui se passe lorsque les DataFrames ont des colonnes différentes (pour axis=0) ou des valeurs d'index différentes (pour axis=1).
outer join (par défaut) -- Tout conserver
df_with_extra = pd.DataFrame({
'product': ['Widget', 'Gadget'],
'units_sold': [200, 250],
'region': ['East', 'West']
})
result = pd.concat([df_jan, df_with_extra], join='outer', ignore_index=True)
print(result)Sortie :
product units_sold revenue region
0 Widget 150 1500.0 NaN
1 Gadget 200 3000.0 NaN
2 Sprocket 80 960.0 NaN
3 Widget 200 NaN East
4 Gadget 250 NaN WestToutes les colonnes des deux DataFrames apparaissent. Les valeurs manquantes sont remplies avec NaN.
inner join -- Conserver uniquement les colonnes communes
result = pd.concat([df_jan, df_with_extra], join='inner', ignore_index=True)
print(result)Sortie :
product units_sold
0 Widget 150
1 Gadget 200
2 Sprocket 80
3 Widget 200
4 Gadget 250Seules les colonnes qui existent dans les deux DataFrames survivent. La colonne revenue (absente de df_with_extra) et la colonne region (absente de df_jan) sont toutes deux supprimées.
Quand utiliser inner join : Lorsque vous voulez un résultat propre sans valeurs NaN et que vous êtes prêt à perdre des colonnes qui n'apparaissent pas dans chaque DataFrame.
Concaténer une liste de DataFrames
L'un des plus grands avantages de pd.concat() par rapport aux autres méthodes de combinaison est qu'il gère n'importe quel nombre de DataFrames en un seul appel. Voici le modèle standard pour combiner des fichiers chargés dans une boucle :
import pandas as pd
# Simulate loading monthly CSV files
months = {
'Jan': {'product': ['Widget', 'Gadget'], 'units': [150, 200]},
'Feb': {'product': ['Widget', 'Gadget'], 'units': [170, 180]},
'Mar': {'product': ['Widget', 'Gadget'], 'units': [190, 210]},
}
dfs = []
for month, data in months.items():
df = pd.DataFrame(data)
df['month'] = month
dfs.append(df)
all_data = pd.concat(dfs, ignore_index=True)
print(all_data)Sortie :
product units month
0 Widget 150 Jan
1 Gadget 200 Jan
2 Widget 170 Feb
3 Gadget 180 Feb
4 Widget 190 Mar
5 Gadget 210 MarCe modèle -- construire une liste de DataFrames, puis appeler concat une seule fois à la fin -- est beaucoup plus rapide que d'ajouter un DataFrame à la fois dans une boucle. Chaque ajout crée une copie complète, mais un seul appel à pd.concat() alloue la mémoire une seule fois.
concat vs merge vs append -- Tableau comparatif
Pandas offre plusieurs façons de combiner des DataFrames. Le bon choix dépend de comment vous voulez les combiner :
| Caractéristique | pd.concat() | pd.merge() | DataFrame.append() |
|---|---|---|---|
| Utilisation principale | Empiler des DataFrames (lignes ou colonnes) | Joindre sur des valeurs de colonnes partagées (comme SQL) | Ajouter des lignes à un DataFrame |
| Nombre d'entrées | N'importe quel nombre à la fois | Deux à la fois | Deux à la fois |
| Logique de correspondance | Alignement par index (ou noms de colonnes) | Correspondance par valeurs de colonne clé | Alignement par noms de colonnes |
| Types de join | outer, inner | inner, left, right, outer, cross | Outer uniquement |
| Comportement par défaut | Outer join, empilement vertical | Inner join sur colonnes partagées | Outer join, ajout de lignes |
| Idéal pour | Combiner des fichiers mensuels, résultats par lots, tables avec le même schéma | Jointures relationnelles (clients + commandes) | Obsolète depuis pandas 2.0 |
| Performance | Rapide pour de nombreux DataFrames | Optimisé pour les jointures à deux tables | Lent (copie les données à chaque appel) |
Quand utiliser chacun
- Utilisez
pd.concat()lorsque vos DataFrames partagent la même structure (mêmes colonnes) et que vous voulez les empiler. Utilisez-le également pour la concaténation horizontale lors de l'alignement par index. - Utilisez
pd.merge()lorsque vous devez faire correspondre des lignes basées sur des valeurs de colonnes -- comme joindre une table de ventes avec une table de produits surproduct_id. Consultez notre guide pandas merge pour plus de détails. - Évitez
DataFrame.append()-- il a été déprécié dans pandas 1.4 et supprimé dans pandas 2.0. Utilisezpd.concat([df1, df2])à la place.
Erreurs courantes et corrections
1. Les colonnes ne s'alignent pas
Lors de la concaténation de DataFrames avec des noms de colonnes différents, le outer join par défaut remplit les valeurs manquantes avec NaN. Si vous ne vous y attendiez pas, vérifiez vos noms de colonnes :
# Diagnose: compare column names
print(df1.columns.tolist())
print(df2.columns.tolist())
# Fix: rename columns to match before concatenating
df2 = df2.rename(columns={'sales': 'revenue', 'qty': 'units_sold'})
combined = pd.concat([df1, df2], ignore_index=True)2. Incompatibilités de types de données après la concaténation
Si un DataFrame stocke une colonne en int64 et un autre en float64, pandas convertit en float. Pire encore, si l'un la stocke en chaîne de caractères, vous obtenez une colonne de dtype object :
# Check dtypes after concat
combined = pd.concat([df1, df2], ignore_index=True)
print(combined.dtypes)
# Fix: cast before concatenating
df2['units_sold'] = df2['units_sold'].astype(int)
combined = pd.concat([df1, df2], ignore_index=True)3. Valeurs d'index en double
Sans ignore_index=True, la concaténation verticale préserve les index originaux, conduisant à des valeurs en double. Cela pose des problèmes avec les recherches .loc :
combined = pd.concat([df1, df2])
# combined.loc[0] returns TWO rows, not one
# Fix option 1: use ignore_index
combined = pd.concat([df1, df2], ignore_index=True)
# Fix option 2: use verify_integrity to catch the issue early
combined = pd.concat([df1, df2], verify_integrity=True) # raises ValueError4. Concaténation accidentelle le long du mauvais axe
Si votre résultat a deux fois plus de colonnes au lieu de deux fois plus de lignes (ou vice versa), vérifiez le paramètre axis :
# Wrong: this adds columns side by side
wrong = pd.concat([df1, df2], axis=1)
# Right: this stacks rows vertically
right = pd.concat([df1, df2], axis=0)Visualisez vos DataFrames concaténés avec PyGWalker
Après avoir concaténé des données provenant de plusieurs sources, vous devez souvent vérifier le résultat et explorer les tendances dans le jeu de données combiné. Au lieu d'écrire du code de graphiques manuel avec matplotlib ou seaborn, vous pouvez utiliser PyGWalker (opens in a new tab) -- une bibliothèque Python open source qui transforme n'importe quel DataFrame pandas en une interface d'exploration visuelle interactive, semblable à Tableau, directement dans Jupyter Notebook.
import pandas as pd
import pygwalker as pyg
# Combine monthly sales data
df_jan = pd.DataFrame({
'product': ['Widget', 'Gadget', 'Sprocket'],
'units_sold': [150, 200, 80],
'revenue': [1500, 3000, 960],
'month': ['Jan', 'Jan', 'Jan']
})
df_feb = pd.DataFrame({
'product': ['Widget', 'Gadget', 'Sprocket'],
'units_sold': [170, 180, 95],
'revenue': [1700, 2700, 1140],
'month': ['Feb', 'Feb', 'Feb']
})
combined = pd.concat([df_jan, df_feb], ignore_index=True)
# Launch interactive visualization
walker = pyg.walk(combined)Avec PyGWalker, vous pouvez glisser product sur l'axe x et revenue sur l'axe y, puis diviser par month pour comparer instantanément les tendances de revenus entre les périodes -- aucun code de graphique requis. Vous pouvez créer des graphiques à barres, des nuages de points, des graphiques en ligne et plus encore simplement en glissant des champs. C'est particulièrement utile pour vérifier que votre concaténation a fonctionné correctement et que les données de différentes sources s'alignent comme prévu.
Installez PyGWalker avec
pip install pygwalker, ou essayez-le dans Google Colab (opens in a new tab) ou Kaggle (opens in a new tab).
FAQ
Quelle est la différence entre pandas concat et merge ?
pd.concat() empile les DataFrames verticalement (ajout de lignes) ou horizontalement (ajout de colonnes) en s'alignant sur l'index. pd.merge() joint deux DataFrames en faisant correspondre les valeurs dans des colonnes spécifiques, comme un SQL JOIN. Utilisez concat lorsque vos DataFrames ont les mêmes colonnes et que vous voulez combiner les lignes. Utilisez merge lorsque vous devez faire correspondre des lignes basées sur une colonne clé partagée.
Est-ce que pd.concat() modifie les DataFrames originaux ?
Non. pd.concat() retourne toujours un nouveau DataFrame. Les DataFrames originaux restent inchangés. Ceci est cohérent avec le principe de conception de pandas selon lequel les opérations retournent de nouveaux objets plutôt que de modifier les données en place.
Comment concaténer des DataFrames avec des colonnes différentes ?
Utilisez pd.concat() avec le join='outer' par défaut -- il conserve toutes les colonnes de tous les DataFrames et remplit les valeurs manquantes avec NaN. Si vous ne voulez que les colonnes qui apparaissent dans chaque DataFrame, définissez join='inner'. Vous pouvez également renommer les colonnes avant de concaténer pour assurer l'alignement.
Est-ce que pd.concat() est plus rapide que DataFrame.append() ?
Oui. DataFrame.append() a été déprécié dans pandas 1.4 et supprimé dans pandas 2.0. Il appelait pd.concat() en interne mais créait une copie à chaque appel. Lors de la combinaison de nombreux DataFrames, les collecter dans une liste et appeler pd.concat() une seule fois est significativement plus rapide car cela alloue la mémoire une seule fois.
Comment réinitialiser l'index après la concaténation ?
Passez ignore_index=True à pd.concat() : pd.concat([df1, df2], ignore_index=True). Cela remplace les valeurs d'index originales par un nouvel index séquentiel à partir de 0. Alternativement, appelez .reset_index(drop=True) sur le résultat.
Conclusion
La fonction pandas concat() est l'outil de référence pour combiner des DataFrames qui partagent la même structure. Voici les points clés à retenir :
- La concaténation verticale (
axis=0) empile les lignes et est le cas d'utilisation le plus courant -- idéal pour combiner des fichiers mensuels, des résultats par lots ou des jeux de données divisés. - La concaténation horizontale (
axis=1) place les DataFrames côte à côte, en s'alignant sur l'index. - Utilisez
ignore_index=Truepour obtenir un index séquentiel propre (recommandé dans la plupart des cas). - Utilisez
keyspour créer un index hiérarchique qui suit de quelle source chaque ligne provient. - Le paramètre
joincontrôle comment les colonnes non correspondantes sont gérées :'outer'conserve tout,'inner'ne conserve que les colonnes communes. - Collectez toujours les DataFrames dans une liste et appelez
pd.concat()une seule fois, plutôt que d'ajouter dans une boucle. - Utilisez
pd.merge()à la place lorsque vous avez besoin de jointures de style SQL sur les valeurs de colonnes.
Une fois vos données concaténées, des outils comme PyGWalker (opens in a new tab) vous permettent d'explorer visuellement le résultat combiné sans écrire de code de graphique, rendant plus rapide la vérification de votre pipeline de données et la découverte de tendances entre les sources.