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

Modifications de Dataframes

Quand on veut changer une cellule d'un dataframe en utilisant à la fois un numéro de ligne et un nom de colonne : df.loc[df.index[3], 'A']
Renommage des colonnes (ou les lignes) d'un dataframe :
  • on ne peut pas renommer individuellement une colonne : df.columns[0] = 'a' ne marche pas ! (non mutable)
  • par contre, on peut renommer l'ensemble des colonnes : df.columns = ['a', 'B']
  • df.rename(columns = {'A': 'a', 'B': 'b'}) : renomme les colonnes A et B en a et b, mais pas les autres s'il y en a d'autres.
  • df.rename(columns = lambda x: x.lower()) : renommage en donnant une fonction à appliquer.
  • df.rename(index = {0: 'a', 1: 'b'}, inplace = True) : on peut aussi utiliser des numéros, ici sur les lignes, et ici en modifiant directement le dataframe.
  • Pour renommer des colonnes en renvoyant le dataframe avec les colonnes renommées : df.set_axis(['A', 'B', 'C'], axis = 1) (on peut aussi utiliser inplace = True, mais autant utiliser directement df.columns = ['A', 'B' 'C'])
Pour réordonner des colonnes d'un dataframe df avec les colonnes 'A', 'B', C' par exemple :
  • df.reindex(columns = ['B', 'C', 'A']) renvoie le dataframe réordonné par colonne.
  • df[['B', 'C', 'A']] renvoie aussi le dataframe réordonné.
Rajout d'une colonne à un dataframe :
  • df['E'] = pandas.Series([1, 0, 1], index = ['a1', 'a2', 'a3']) : il faut donner une Series dont les noms des individus sont les mêmes que ceux du dataframe.
  • on peut donner la Series dans un ordre différent de celui du dataframe, les données sont rajoutées dans le bon ordre : df['E'] = pandas.Series([0, 1, 1], index = ['a2', 'a1', 'a3']).
  • on peut rajouter une valeur constante sur toutes les lignes : df['E'] = 0
  • par défaut, les colonnes rajoutées le sont à la fin.
  • df.assign(E = df['A'] + df['B'], F = 2 * df['A']) : renvoie une copie du dataframe avec deux nouvelles colonnes E et F (sans modifier le dataframe original).
  • on peut enchaîner les assign : df2 = df.assign(E = df['A'] + df['B']).assign(F = 2 * df['E'])
  • df2.insert(0, 'C', [8, 4, 8]) : insère une colonne à une position donnée.
  • df.insert(0, 'E', 'value') : insère une colonne avec une valeur constante, à une position donnée
Destruction de colonnes d'un dataframe :
  • del df['A'] : permet de détruire la colonne A.
  • df2.drop(['a', 'c'], inplace = True) : détruit les lignes d'index 'a' et 'c'
  • df.drop(['A', 'C'], axis = 1, inplace = True) : permet de détruire plusieurs colonnes en même temps.
  • df.drop(columns = ['A', 'C'], inplace = True) : alternative à l'indication de l'axis.
  • df.drop(index = ['a', 'c'], inplace = True) : alternative à l'indication de l'axis (destruction de lignes).
s = df.pop('A') : enlève la colonne A et renvoie la série correspondante.
Pour changer le type de colonnes d'un dataframe :
  • df.astype(numpy.float64) : renvoie un dataframe avec toutes les colonnes converties dans le type indiqué.
  • df.astype({'A': int, 'B': numpy.float64}) : renvoie un dataframe avec les colonnes A et B converties selon les types indiqués.
Modification des valeurs d'une colonne :
  • on peut faire df['A'][df['A'] < 2] = 0, mais souvent, Warning indiquant qu'on modifie une copie d'une slice d'un dataframe, donc à éviter.
  • préférer : df['A'] = df['A'].apply(lambda x: 0 if x < 2 else x)
  • en utilisant toutes les valeurs de la ligne : axis = 1 indique que la valeur passée à la fonction est la ligne (sous forme de Series) :
    df = pandas.DataFrame({'A': [1, 3, 5], 'B': [7, 6, 2]})
    df['C'] = df.apply(lambda x: 0 if x['A'] > x['B'] else x['A'], axis = 1)
          
    donne :
    
       A  B C
    0  1  7 1
    1  3  6 3
    2  0  2 0
        
  • on peut aussi utiliser les valeurs d'une colonne : df.apply(numpy.sum, axis = 0) donne la series :
    
    A     9
    B    15
        
  • avec l'appel par ligne, on peut aussi faire un broadcast aux mêmes dimensions que le dataframe d'origine : df.apply(numpy.mean, axis = 1, result_type = 'broadcast') donne :
    
       A  B
    0  4  4
    1  4  4
    2  3  3
          
    Attention : ça conserve le type, ici int64, d'où le fait d'avoir 4 au lieu de 3.5 par exemple !
Valeurs non définies :
  • df.notna() : renvoie un dataframe de mẽme dimensions que l'original, mais avec des valeurs booléenes True si la valeur est définie, False si la valeur est NA.
  • on utilise ici le dataframe : df = pandas.DataFrame({'A': [1, numpy.nan, 3], 'B': [numpy.nan, 20, 30], 'C': [7, 6, 5]}) :
    
        A   B  C
    0   1 NaN  7
    1 NaN  20  6
    2   3  30  5
        
  • df.dropna(how = 'any') ou df.dropna() : renvoie un dataframe avec les lignes contenant au moins une valeur NaN supprimée.
  • df.dropna(how = 'all') : : supprime les lignes où toutes les valeurs sont NaN.
  • df.dropna(axis = 1, how = 'any') : supprime les colonnes ayant au moins un NaN plutôt que les lignes (le défaut est axis = 0).
  • df.dropna(inplace = True) : ne renvoie rien, mais fait la modification en place.
  • df.fillna(0) : renvoie un dataframe avec toutes les valeurs NaN remplacées par 0.
  • df['A'].fillna(0, inplace = True) : remplace tous les NA de la colonne A par 0, sur place.
  • df.isnull() : renvoie un dataframe de booléens, avec True dans toutes les cellules non définies.
  • df = df.replace(numpy.inf, 99) : remplace les valeurs infinies par 99 (on peut utiliser inplace = True)
Copie d'un dataframe :
  • df2 = df.copy() : df2 est alors un dataframe indépendant.
  • par contre, si on fait : df2 = df et que l'on modifie df2, df est également modifié (df et df2 pointent vers le même objet).
Changement des valeurs en batch d'un dataframe :
  • df[df > 0] = 1 remplace toutes les valeurs différentes de 0 par 1
  • pour positionner à une valeur donnée une colonne pour les lignes vérifiant une conditions une autre colonne :
    df = pandas.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
    df.loc[df['B'] >= 5,'A'] = 0
        
    donne :
    
       A  B
    0  1  4
    1  0  5
    2  0  6
        
  • on peut aussi affecter des valeurs différentes, par exemple ici doubler les valeurs :
    df = pandas.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
    df.loc[df['B'] >= 5,'A'] = 2 * df.loc[df['B'] >= 5,'A']
        
    donne :
    
       A  B
    0  1  4
    1  4  5
    2  6  6
        
  • replace :
    • df.replace(1, 5) : remplace tous les 1 par 5.
    • df.replace([1, 2], [5, 7]) : remplace tous les 1 par 5 et tous les 2 par 7.
    • df.replace({1: 5, 2: 7}) : remplace tous les 1 par 5 et tous les 2 par 7.
    on peut utiliser inplace = True pour modifier directement le dataframe.
Concaténation de colonnes séparées par des tirets : df.apply(lambda x: '-'.join(x), axis = 1)
Pour enlever les lignes redondantes dans un dataframe (avoir des lignes uniques), avec par exemple df = pandas.DataFrame({'A': [4, 2, 4, 2], 'B': [7, 3, 7, 3], 'C': [1, 8, 1, 9]}) :
  • df.drop_duplicates() : renvoie un dataframe avec les lignes redondantes enlevées en n'en conservant qu'une seule (ici 3 lignes restant)
  • df.drop_duplicates(keep = False) : renvoie un dataframe avec les lignes redondantes toutes enlevées (ici 2 lignes restant)
  • df.drop_duplicates(inplace = True) : fait la modification en place.
  • df.drop_duplicates(subset = ['A', 'B']) : renvoie un dataframe avec les doublons enlevés en considérant seulement les colonnes A et B, et en renvoyant la 1ère ligne pour chaque groupe ayant mêmes valeurs de A et B.
  • df.drop_duplicates(subset = ['A', 'B'], keep = 'last') : on conserve la dernière ligne plutôt que la première (keep = first, qui est le défaut).
Transposition :
  • df.T : renvoie le dataframe transposé.
  • ici, cela donne :
    
        a1    a2    a3
    A  1.1   2.7   5.3
    B  2.0  10.0   9.0
    C  3.3   5.4   1.5
    D  4.0   7.0  15.0
        
  • on peut aussi faire df.transpose()
Pour faire un shuffle des lignes d'un dataframe : df2 = df.sample(frac = 1)

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