Mis a jour le 2025-04-14, 12:10

Concaténations et jointures de dataframes

Juxtaposition de dataframes :
  • pour concaténer 2 dataframes (ou plus) ayant les mêmes colonnes les uns en dessous des autres :
    df1 = pandas.DataFrame({'A': [3, 5], 'B': [1, 2]}, index = [0, 1])
    df2 = pandas.DataFrame({'A': [6, 7], 'B': [4, 9]}, index = [2, 3])
    pandas.concat([df1, df2])
        
    donne
    
       A  B
    0  3  1
    1  5  2
    2  6  4
    3  7  9
        
  • on peut concaténer ainsi des dataframes même si les index sont identiques, ils seront juxtaposés avec des valeurs d'index répétées : df1 = pandas.DataFrame({'A': [3, 5], 'B': [1, 2]}); df2 = pandas.DataFrame({'A': [6, 7], 'B': [4, 9]}); pandas.concat([df1, df2]) donne :
    
       A  B
    0  3  1
    1  5  2
    0  6  4
    1  7  9
        
  • si les dataframes n'ont pas les mêmes colonnes, par défaut, des NaN sont mis aux endroits non définis : df1 = pandas.DataFrame({'A': [3, 5], 'B': [1, 2]}); df2 = pandas.DataFrame({'A': [6, 7], 'C': [4, 9]}); pandas.concat([df1, df2]) donne :
    
       A    B    C
    0  3  1.0  NaN
    1  5  2.0  NaN
    0  6  NaN  4.0
    1  7  NaN  9.0
        
  • si les dataframes n'ont pas les mêmes colonnes et qu'on veut conserver seulement les colonnes communes, intersection (sans avoir de NaN) : pandas.concat([df1, df2], join = 'inner') donne :
    
       A
    0  3
    1  5
    0  6
    1  7
        
    (le défaut de join est 'outer', conservation de toutes les colonnes, leur réunion).
  • on peut ignorer les valeurs de l'index dans la concaténation (met un index de 0 à n - 1) : df1 = pandas.DataFrame({'A': [3, 5], 'B': [1, 2]}); df2 = pandas.DataFrame({'A': [6, 7], 'B': [4, 9]}); pandas.concat([df1, df2], ignore_index = True) donne :
    
       A  B
    0  3  1
    1  5  2
    2  6  4
    3  7  9
        
  • on peut rajouter un niveau hierarchique d'index en attribuant une clef à chaque dataframe de départ : df1 = pandas.DataFrame({'A': [3, 5], 'B': [1, 2]}); df2 = pandas.DataFrame({'A': [6, 7], 'B': [4, 9]}); pandas.concat([df1, df2], keys = ['a', 'b']) donne :
    
         A  B
    a 0  3  1
      1  5  2
    b 0  6  4
      1  7  9
        
    (et du coup, reset_index() permet de passer les valeurs d'index 'a' et 'b' comme nouvelle colonne).
  • plutôt que de donner un argument keys, on peut donner un dictionnaire de frames plutôt qu'une list, c'est équivalent : pandas.concat({'a': df1, 'b': df2}).
  • juxtaposition de colonnes plutôt que de lignes : df1 = pandas.DataFrame({'A': [3, 5], 'B': [1, 2]}); df2 = pandas.DataFrame({'C': [6, 7], 'D': [4, 9]}); pandas.concat([df1, df2], axis = 1) donne :
    
       A  B  C  D
    0  3  1  6  4
    1  5  2  7  9
        
    (le défaut de concaténation des lignes est axis = 0)
  • on peut concaténér des dataframes et des séries, par exemple df1 = pandas.DataFrame({'A': [3, 5], 'B': [1, 2]}); s = pandas.Series([7, 9], name = 'C'); pandas.concat([df1, s], axis = 1) donne :
    
       A  B  C
    0  3  1  7
    1  5  2  9
        
  • éviter de faire des concaténations répétées, préférer construire une liste de dataframes et faire une seule concaténation, pour des raisons de performances.
Pour rajouter le total par colonne : pandas.concat([df, pandas.DataFrame(df.sum(), columns = ['total']).T])
Jointures : c'est le même principe qu'en sql :
  • jointure simple (inner) qui par défaut utilise les noms des colonnes qui sont communs : df1 = pandas.DataFrame({'A': [3, 5], 'B': [1, 2]}); df2 = pandas.DataFrame({'A': [5, 3, 7], 'C': [9, 2, 0]}); pandas.merge(df1, df2) donne :
    
       A  B  C
    0  3  1  2
    1  5  2  9
        
  • on peut aussi faire : df1.merge(df2)
  • on peut indiquer explicitement les colonnes sur lequelles on veut faire la jointure si c'est une partie seulement des colonnes de même non : df1 = pandas.DataFrame({'A': [3, 5], 'B': [1, 2]}); df2 = pandas.DataFrame({'A': [5, 3, 7], 'B': [9, 2, 0]}); pandas.merge(df1, df2, on = ['A']) (ou df1.merge(df2, on = ['A'])) donne :
    
       A  B_x  B_y
    0  3    1    2
    1  5    2    9
        
  • jointure externe : les lignes qui n'ont pas la clef commune sont quand mêmes présentes (comme en sql) : pandas.merge(df1, df2, how = 'outer')
    
       A    B  C
    0  3  1.0  2
    1  5  2.0  9
    2  7  NaN  0
        
  • on peut aussi faire une jointure externe gauche ou droite comme en sql avec how = 'left' ou how = 'right'
  • on peut changer les extensions rajoutées sur les colonnes de même nom non incluses dans la jointure (par défaut _x et -y) : pandas.merge(df1, df2, on = ['A'], suffixes = ('_1', '_2')) donne :
    
       A  B_1  B_2
    0  3    1    2
    1  5    2    9
        
  • on peut aussi faire une jointure sur des colonnes qui ne s'appellent pas pareil dans les 2 dataframes : df1 = pandas.DataFrame({'C': [3, 5], 'B': [1, 2]}); df2 = pandas.DataFrame({'D': [5, 3, 7], 'E': [9, 2, 0]}); pandas.merge(df1, df2, left_on = ['C'], right_on = ['D']) donne :
    
       B  C  D  E
    0  1  3  3  2
    1  2  5  5  9
        
  • on peut aussi faire une jointure sur l'index : df1 = pandas.DataFrame({'A': [3, 5], 'B': [1, 2]}, index = [0, 1]); df2 = pandas.DataFrame({'D': [5, 3, 7], 'E': [9, 2, 0]}, index = [2, 1, 0]); df1.join(df2) donne :
    
       A  B  D  E
    0  3  1  7  0
    1  5  2  3  2
        
  • et la jointure sur l'index peut aussi être externe (des 2 côtés ou d'un côté), par exemple : df1 = pandas.DataFrame({'A': [3, 5], 'B': [1, 2]}, index = [0, 1]); df2 = pandas.DataFrame({'D': [5, 3, 7], 'E': [9, 2, 0]}, index = [2, 1, 0]); df1.join(df2, how = 'outer') donne :
    
         A    B  D  E
    0  3.0  1.0  7  0
    1  5.0  2.0  3  2
    2  NaN  NaN  5  9
        
  • la jointure sur les index peut aussi être faite avec pandas.merge(df1, df2, left_index = True, right_index = True) au lieu de df1.join(df2)
  • pandas.merge(df1, df2, sort = False) : ne trie pas les colonnes de jointure dans l'ordre (le défaut est de les trier, mais cela a un impact sur la performance).
Jointure par index :
  • df1.join(df2) : faite une jointure par l'index, par défaut, une left join.
  • pandas.concat([df1, df2], axis = 1) : par défaut, fait une outer join.
  • pandas.merge(df1, df2, left_index = True, right_index = True) : par défaut, fait une inner join

Copyright python-simple.com
programmer en python, tutoriel python, graphes en python, Aymeric Duclert