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

Réorganisation des dataframes

Pivotage dans fonction d'aggrégation :
  • il faut avoir une seule valeur par combinaison de ligne et de colonne.
  • utile notamment si les valeurs sont du texte.
  • Si df = pandas.DataFrame({'A': ['a', 'a', 'b', 'b', 'c', 'c'], 'T': ['yes', 'no', 'yes', 'no', 'yes', 'no'], 'V': [4, 2, 5, 2, 7, 3]}), c'est à dire :
       A    T  V
    0  a  yes  4
    1  a   no  2
    2  b  yes  5
    3  b   no  2
    4  c  yes  7
    5  c   no  3
        
    alors df.pivot(index = 'A', columns = 'T', values = 'V') renvoie :
    
    T  no  yes
    A         
    a   2    4
    b   2    5
    c   3    7
        
  • si il y a des combinaisons qui manquent, on a un NaN à ces places-là.
  • si pour certaines combinaisons on a plusieurs lignes (plusieurs valeurs) : erreur (ValueError)
pivot_table : plus souple que pivot :
  • si pour certaines combinaisons on a plusieurs lignes (plusieurs valeurs), fait la moyenne : df = pandas.DataFrame({'A': ['a', 'a', 'b', 'b', 'c', 'c', 'c'], 'T': ['yes', 'no', 'yes', 'no', 'yes', 'no', 'no'], 'V': [4, 2, 5, 2, 7, 3, 1]}); df.pivot_table(index = 'A', columns = 'T', values = 'V') donne :
    
    T  no  yes
    A         
    a   2    4
    b   2    5
    c   2    7
        
  • on peut utiliser une autre fonction que la moyenne : df.pivot_table(index = 'A', columns = 'T', values = 'V', aggfunc = 'median'). Pour aggfunc, on peut utiliser les noms des fonctions ('min', 'median', ...) ou les fonctions elles-mêmes (min, numpy.median, len).
  • Si df est un dataframe avec 2 colonnes 'A' et 'B' et on veut compter le nombre d'ocurrence de chaque paires, avec A en ligne et B en colonne : df.pivot_table(index = 'A', columns = 'B', aggfunc = len).fillna(0)
  • df.pivot_table(index = 'A', columns = 'T', values = 'V', fill_value = 0) : fill_value indique la valeur à mettre au lieu de NaN pour les combinaisons manquantes.
  • df.pivot_table(index = 'A', columns = ['B', 'C'], values = 'V') : on peut utiliser plusieurs colonnes.
  • df.pivot_table(index = 'A', columns = 'B', values = ['V1', 'V2'] : on peut utiliser plusieurs valeurs (on aura alors df.columns qui sera à plusieurs niveaux)
  • pour réintégrer les valeurs lignes de l'index comme colonnes, faire : df = df.reset_index() (ou df.reset_index(inplace = True))
  • après df.pivot_table(), on peut faire :
    • d'abord une mise à plat des colonnes si plusieurs colonnes données : df.columns = ['_'.join(x) for x in df.columns.values]
    • puis une conversion de l'index hierarchique ligne en simples colonnes : df = df.reset_index()
  • attention, par défaut, pivot_table élimine les lignes où toutes les valeurs sont NaN. Si on peut les garder, utiliser df.pivot_table(..., dropna = False)
Stacking : consiste à empiler les différentes colonnes d'un dataframe :
  • si df = pandas.DataFrame({'A': [5, 4, 1], 'B': [8, 9, 6]}), alors df.stack() donne la Series multi-index :
    
    0  A    5
       B    8
    1  A    4
       B    9
    2  A    1
       B    6
        
  • si on veut avoir un dataframe, faire : df2 = df.stack().reset_index(level = 1); df2.columns = ['condition', 'value']; df2.index = range(len(df2)) donne le dataframe :
    
      condition  value
    0         A      5
    1         B      8
    2         A      4
    3         B      9
    4         A      1
    5         B      6
        
Si on part d'un dataframe df = pandas.DataFrame({'person': ['a', 'a', 'b', 'b', 'c', 'c'], 'condition': ['A', 'B', 'A', 'B', 'A', 'B'], 'value': [5, 8, 4, 9, 1, 6]}) et que l'on veut un dataframe avec comme colonnes person, A et B :
  • df = df.pivot(index = 'person', columns = 'condition', values = 'value').reset_index(); df.columns.name = None (pour faire passer 'person' comme colonne normale et supprimer le nom de la colonne.
  • donne :
    
      person  A  B
    0      a  5  8
    1      b  4  9
    2      c  1  6
        
  • si le frame de départ n'est pas équilibré avec certaines combinaisons absentes : on aura des NaN.
  • par contre, s'il y a des combinaisons redondantes, on aura une erreur (utiliser éventuellement pivot_table dans ce cas si on accepte des faire des moyennes !)
Réorganisation avec melt pour empiler les données associés à certaines colonnes définies comme clefs :
  • pour df = pandas.DataFrame({'A': ['a', 'b', 'b'], 'B': ['yes', 'no', 'no'], 'val1': [4, 2, 5], 'val2': [7, 8, 10], 'val3': [9, 3, 15]}) :
    
       A    B  val1  val2  val3
    0  a  yes     4     7     9
    1  b   no     2     8     3
    2  b   no     5    10    15
        
  • df.melt(id_vars = ['A', 'B'], var_name = 'myParam', value_name = 'myValue') renvoie :
    
       A    B myParam  myValue
    0  a  yes    val1        4
    1  b   no    val1        2
    2  b   no    val1        5
    3  a  yes    val2        7
    4  b   no    val2        8
    5  b   no    val2       10
    6  a  yes    val3        9
    7  b   no    val3        3
    8  b   no    val3       15
        
  • pour transformer un dataframe en dataframe à 2 colonnes en conservant l'index (qui a alors des valeurs répétées) :
    df = pandas.DataFrame({'A' : [1,2], 'B': [3, 4]}, index = ['a', 'b'])
    df.melt(id_vars = [], var_name = 'myVar', value_name = 'myValue', ignore_index = False)	
          
    ça donne :
          
     	myVar 	myValue
    a 	A 	1
    b 	A 	2
    a 	B 	3
    b 	B 	4
    	
  • si df = pandas.DataFrame({'A': [1, 2], 'B': [3, 4]}), df.melt(var_name = 'myVar', value_name = 'myValue') donne :
    
      myVar  myValue
    0     A        1
    1     A        2
    2     B        3
    3     B        4
          
One-hot encoding : transforme les colonnes de type catégories en autant de colonnes que de valeurs avec un 1 quand c'est la bonne valeur et des 0 ailleurs :
  • >>> df = pandas.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'a']})
    >>> pandas.get_dummies(df, columns = ['B'])
          
    donne :
    
       A  B_a  B_b
    0  1    1    0
    1  2    0    1
    2  3    1    0
        
  • columns : indique les colonnes à transformer (les autres restent intactes).
  • prefix : le nom du préfixe à mettre dans la colonne (par défaut, le nom de la colonne d'origine)
  • prefix_sep : le séparateur entre le nom de la colonne d'origine et la valeur de la colonne (défaut est '_').

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