Dictionnaires et Pandas#

Vidéo: Dictionnaires#

Les dictionnaires#

Un dictionnaire ressemble à une liste mais il est plus général. Alors que les indices d’une liste doivent être des entiers, dans un dictionnaire, les indices peuvent être de types différents.

Un dictionnaire contient une collection d’indices, appelés clés, et une collection de valeurs. À chaque clé correspond une valeur, ce que l’on appelle une paire clé-valeur, ou item.

La syntaxe pour définir un dictionnaire est :

my_dict = {
   "key1": "value1",
   "key2": "value2",
}

Définissons 2 listes nous donnant les pays européens et leur capitale :

pays = ['allemagne', 'autriche', 'belgique', 'bulgarie', 'chypre', 'croatie', 'danemark', 'espagne', 'estonie', 
        'finlande', 'france', 'grèce', 'hongrie', 'irlande', 'italie', 'lettonie', 'lituanie', 'luxembourg', 
        'malte', 'pays-bas', 'pologne', 'portugal', 'république tchèque', 'roumanie', 'slovaquie', 'slovénie', 'suède']
capitales = ['berlin', 'vienne', 'bruxelles', 'sofia', 'nicosie', 'zagreb', 'copenhague', 'madrid', 'tallinn', 
             'helsinki', 'paris', 'athènes', 'budapest', 'dublin', 'rome', 'riga', 'vilnius', 'luxembourg', 'la valette',
             'amsterdam', 'varsovie', 'lisbonne', 'prague', 'bucarest', 'bratislava', 'ljubljana', 'stockholm']

Nous voulons trouver la capitale de la Hongrie. Nous pouvons utiliser la méthode de liste index() :

# Trouver l'indice de 'hongrie'
ind_hongrie = pays.index('hongrie')

# Afficher la capitale de la Hongrie
print(capitales[ind_hongrie].capitalize())
Budapest

Maintenant, définissons un dictionnaire contenant les même informations :

europe = {
    'allemagne' : 'berlin',
    'autriche' : 'vienne',
    'belgique' : 'bruxelles',
    'bulgarie' : 'sofia',
    'chypre' : 'nicosie',
    'croatie' : 'zagreb',
    'danemark' : 'copenhague',
    'espagne' : 'madrid',
    'estonie' : 'tallinn',
    'finlande' : 'helsinki',
    'france' : 'paris',
    'grèce' : 'athènes',
    'hongrie' : 'budapest',
    'irlande' : 'dublin',
    'italie' : 'rome',
    'lettonie' : 'riga',
    'lituanie' : 'vilnius',
    'luxembourg' : 'luxembourg',
    'malte' : 'la valette',
    'pays-bas' : 'amsterdam',
    'pologne' : 'varsovie',
    'portugal' : 'lisbonne',
    'république tchèque' : 'prague',
    'roumanie' : 'bucarest',
    'slovaquie' : 'bratislava',
    'slovénie' : 'ljubljana',
    'suède' : 'stockholm'
}

Pour accéder à la valeur associée à une clé donnée, il suffit alors d’utiliser la clé en indice du dictionnaire. Ainsi, pour afficher la capitale de la Hongrie :

europe['hongrie']
'budapest'

Il est facile avec un dictionnaire d’ajouter ou enlever une paire clé-valeur, ou bien de changer une valeur :

# Ajouter la Turqie au dictionnaire
europe['turquie'] = 'istanbul'

# Vérifier que le pays est bien contenu dans le dictionnaire
'turquie' in europe
True
# Changer le nom de la capitale de la Turquie (et oui ce n'est pas Istanbul...)
europe['turquie'] = 'ankara'

# Afficher la capitale de la Turquie
print(europe['turquie'].capitalize())
Ankara
# Enlever la paire clé-valeur du dictionnaire
del(europe['turquie'])

# Vérifier que le pays n'est pas contenu dans le dictionnaire
'turquie' in europe
False

Vidéo: L’objet DataFrame#

Pandas DataFrames#

Pandas est un module de Python pour l’analyse et la manipulation de données. L’objet de base de Pandas est le DataFrame, qui est un tableau similaire aux feuilles Excel ou LibreOffice que vous devez connaître. Le module Pandas fonctionne en harmonie avec les modules Numpy et Matplotlib vus dans les cours précédents.

Voyons comment créer un DataFrame à partir d’un dictionnaire. Nous allons reprendre les listes créées plus haut sur les pays et capitales européennes, les transformer en tableaux Numpy, et y ajouter d’autres informations :

# Importation du module Numpy
import numpy as np

# Importation du module Pandas
import pandas as pd

# Création des tableaux Numpy à partir des listes des pays et des capitales : type string
np_pays = np.array(pays)
np_capitales = np.array(capitales)

# Liste avec les populations des pays européens : type integer
np_population = np.array([82162000, 8700471, 11289853, 7153784, 848319, 4190669, 5659715, 46438422, 1315944, 
                       5401267, 66661621, 10793526, 9830485, 4658530, 60665551, 1968957, 2888558, 576249, 
                       434403, 16979120, 37967209, 10341330, 10553853, 19759968, 5426252, 2064188, 9851017],
                       dtype = 'int64')

# Liste avec les dates d'adhésion des pays à l'UE : type datetime
np_date = np.array(['1957', '1995', '1957', '2007', '2004', '2013', '1973', '1986', '2004', '1995',
                    '1957', '1981', '2004', '1973', '1957', '2004', '2004', '1957', '2004', '1957',
                    '2004', '1986', '2004', '2007', '2004', '2004', '1995'],
                    dtype = 'datetime64[Y]')
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[11], line 5
      2 import numpy as np
      4 # Importation du module Pandas
----> 5 import pandas as pd
      7 # Création des tableaux Numpy à partir des listes des pays et des capitales : type string
      8 np_pays = np.array(pays)

ModuleNotFoundError: No module named 'pandas'

Maintenant, créons un dictionnaire en utilisant les tableaux Numpy dans les paires clé-valeur :

dic_europe = {
    "pays" : np_pays,
    "capitale" : np_capitales,
    "population" : np_population,
    "date d'adhésion" : np_date
}

Pour créer le DataFrame à partir du dictionnaire il suffit d’utiliser la fonction DataFrame() de Pandas :

# Création du DataFrame
df_europe = pd.DataFrame(data = dic_europe)

# Affichage du DataFrame
df_europe
pays capitale population date d'adhésion
0 allemagne berlin 82162000 1957-01-01
1 autriche vienne 8700471 1995-01-01
2 belgique bruxelles 11289853 1957-01-01
3 bulgarie sofia 7153784 2007-01-01
4 chypre nicosie 848319 2004-01-01
5 croatie zagreb 4190669 2013-01-01
6 danemark copenhague 5659715 1973-01-01
7 espagne madrid 46438422 1986-01-01
8 estonie tallinn 1315944 2004-01-01
9 finlande helsinki 5401267 1995-01-01
10 france paris 66661621 1957-01-01
11 grèce athènes 10793526 1981-01-01
12 hongrie budapest 9830485 2004-01-01
13 irlande dublin 4658530 1973-01-01
14 italie rome 60665551 1957-01-01
15 lettonie riga 1968957 2004-01-01
16 lituanie vilnius 2888558 2004-01-01
17 luxembourg luxembourg 576249 1957-01-01
18 malte la valette 434403 2004-01-01
19 pays-bas amsterdam 16979120 1957-01-01
20 pologne varsovie 37967209 2004-01-01
21 portugal lisbonne 10341330 1986-01-01
22 république tchèque prague 10553853 2004-01-01
23 roumanie bucarest 19759968 2007-01-01
24 slovaquie bratislava 5426252 2004-01-01
25 slovénie ljubljana 2064188 2004-01-01
26 suède stockholm 9851017 1995-01-01

On voit que :

  • les clés du dictionnaire ont été utilisées pour nommer les colonnes du DataFrame,

  • les listes ont été utilisées pour remplir chaque colonne

  • les lignes sont étiquetées, par défaut avec des entiers à partir de l’indice 0 (mais il est possible d’utiliser d’autres types pour les étiquettes, comme pour les clés d’un dictionnaire, ce que nous verrons au paragraphe sur l’objet index)

Nous pouvons vérifier le type du DataFrame avec la fonction type() :

# Affichage du type
print(type(df_europe))
<class 'pandas.core.frame.DataFrame'>

Les attributs de DataFrame sont :

Attributs

Description

ndim

nombre de dimensions

shape

forme, nombre d’éléments dans chaque dimension

size

nombre d’éléments

print('ndim :', df_europe.ndim)
print('shape :', df_europe.shape)
print('size :', df_europe.size)
ndim : 2
shape : (27, 4)
size : 108

Les DataFrame contiennent parfois beaucoup de lignes. On peut afficher seulement les premières ou dernières lignes avec les méthodes head() et tail() :

# Afficher les 2 premières lignes
df_europe.head(n = 2)
pays capitale population date d'adhésion
0 allemagne berlin 82162000 1957-01-01
1 autriche vienne 8700471 1995-01-01
# Afficher les 2 dernières lignes
df_europe.tail(n = 2)
pays capitale population date d'adhésion
25 slovénie ljubljana 2064188 2004-01-01
26 suède stockholm 9851017 1995-01-01

L’objet Series#

Il est possible d’extraire une colonne en mettant en indice le nom de la colonne :

# Extraire la colonne pays du DataFrame
col_pays = df_europe['pays']

# Ou de manière similaire
col_pays = df_europe.pays

# Affichage
print(col_pays)
0              allemagne
1               autriche
2               belgique
3               bulgarie
4                 chypre
5                croatie
6               danemark
7                espagne
8                estonie
9               finlande
10                france
11                 grèce
12               hongrie
13               irlande
14                italie
15              lettonie
16              lituanie
17            luxembourg
18                 malte
19              pays-bas
20               pologne
21              portugal
22    république tchèque
23              roumanie
24             slovaquie
25              slovénie
26                 suède
Name: pays, dtype: object

On voit que l’on a extrait la colonne mais aussi les étiquettes des lignes et d’autres informations telles que l’étiquette de la colonne. Une colonne extraite de cette manière est un objet Series de Pandas :

print(type(col_pays))
<class 'pandas.core.series.Series'>

On accède aux valeurs d’un objet Series de la même manière qu’un dictionnaire, c’est-à-dire en écrivant l’étiquette en indice de l’objet :

# Afficher la valeur de la "Series" col_pays correspondant a l'étiquette 23
print(col_pays[23])
roumanie

Pour accéder à une ligne, il faut utiliser un accesseur .loc[] :

# Extraire la ligne 23 du DataFrame
ligne_23 = df_europe.loc[23]

# Affichage
print(ligne_23)
pays                          roumanie
capitale                      bucarest
population                    19759968
date d'adhésion    2007-01-01 00:00:00
Name: 23, dtype: object

Une ligne extraite de cette façon est aussi un objet Series :

type(ligne_23)
pandas.core.series.Series

Les noms des colonnes ont été utilisés pour étiqueter les lignes de ce nouvel objet, et l’étiquette de la ligne a été utilisée pour nommer l’objet.

Exercice#

  1. Créer un objet Series contenant la colonne date d’adhésion

  2. Créer un objet Series contenant la ligne 12

col_date_adhesion = df_europe["date d'adhésion"]

print(type(col_date_adhesion))
<class 'pandas.core.series.Series'>
ligne_12 = df_europe.loc[12]
print(ligne_12)
pays                           hongrie
capitale                      budapest
population                     9830485
date d'adhésion    2004-01-01 00:00:00
Name: 12, dtype: object

L’objet Index#

On peut extraire les étiquettes des lignes et des colonnes avec .index et .columns :

# Étiquettes des lignes
print(df_europe.index)
RangeIndex(start=0, stop=27, step=1)
# Étiquette des lignes
print(df_europe.columns)
Index(['pays', 'capitale', 'population', 'date d'adhésion'], dtype='object')

Ces étiquettes sont des objet Pandas appelés Index. Ce sont des tableaux Numpy immuables, c’est-à-dire qu’on ne peut pas modifier leurs éléments.

On peut par contre changer un index entier :

# Modifier les étiquettes des lignes du DataFrame en les faisant commencer à 1
df_europe.index = np.arange(1, 28)

# Afficher la premiere ligne
df_europe.head(n = 1)
pays capitale population date d'adhésion
1 allemagne berlin 82162000 1957-01-01

Accéder et modifier les données#

On peut accéder aux données du DataFrame pour les extraire ou les modifier grâce à des accesseurs :

Accesseur

Description

.loc[]

accepte les étiquettes des lignes ou colonnes et retourne un objet Series ou DataFrame

.iloc[]

accepte les indices des lignes ou colonnes et retourne un objet Series ou DataFrame

.at[]

accepte les étiquettes des lignes ou colonnes et retourne une valeur unique

.iat[]

accepte les indices des lignes ou colonnes et retourne une valeur unique

Comme pour les tableaux Numpy, les accesseurs supportent l’indexation et le tranchage. Voyons quelques exemples :

# Extraire les capitales des 3 premiers pays
print(df_europe.loc[1:4, 'capitale'])
1       berlin
2       vienne
3    bruxelles
4        sofia
Name: capitale, dtype: object

Attention, avec .loc[] on a utilisé les étiquettes des lignes, décalées de 1 par rapport à leur indice. Pour extraire le même objet Series avec iloc[], on écrira :

# Extraire les capitales des 3 premiers pays
print(df_europe.iloc[0:4, 1])
1       berlin
2       vienne
3    bruxelles
4        sofia
Name: capitale, dtype: object

Note :

  • lorsqu’on accède par étiquettes, la notation m:n signifie \([m,n]\),

  • lorsqu’on accède par indices, la notation m:n signifie \([m,n[\).

Attention aux erreurs !

Comme pour les tableaux Numpy, on peut trancher en fournissant une liste :

# Extraire les noms et les populations des pays 3 à 7
df_europe.loc[3:7, ['pays', 'population']]
pays population
3 belgique 11289853
4 bulgarie 7153784
5 chypre 848319
6 croatie 4190669
7 danemark 5659715

Avec l’accesseur iloc[] on écrira :

# Extraire les noms et les populations des pays 3 à 7
df_europe.iloc[2:7, [0, 2]]
pays population
3 belgique 11289853
4 bulgarie 7153784
5 chypre 848319
6 croatie 4190669
7 danemark 5659715

Pour accéder à une valeur en particulier :

# Nom du pays 23
print(df_europe.at[23, 'pays'])

# Ou avec les indices
print(df_europe.iat[22, 0])
république tchèque
république tchèque

Exercice#

  1. Extraire les date d’adhésion des pays avec les étiquettes 12 et 25

  2. Extraire la population du pays avec l’étiquette 6

col_date_adhesion.loc[12:25]
12   2004-01-01
13   1973-01-01
14   1957-01-01
15   2004-01-01
16   2004-01-01
17   1957-01-01
18   2004-01-01
19   1957-01-01
20   2004-01-01
21   1986-01-01
22   2004-01-01
23   2007-01-01
24   2004-01-01
25   2004-01-01
Name: date d'adhésion, dtype: datetime64[ns]
print(df_europe.index)
Int64Index([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
            18, 19, 20, 21, 22, 23, 24, 25, 26, 27],
           dtype='int64')
df_europe.iloc[:, [2]]
population
1 82162000
2 8700471
3 11289853
4 7153784
5 848319
6 4190669
7 5659715
8 46438422
9 1315944
10 5401267
11 66661621
12 10793526
13 9830485
14 4658530
15 60665551
16 1968957
17 2888558
18 576249
19 434403
20 16979120
21 37967209
22 10341330
23 10553853
24 19759968
25 5426252
26 2064188
27 9851017

Insérer et supprimer des données#

Pour insérer une nouvelle ligne, on peut créer un objet Series et l’ajouter au DataFrame avec la méthode .append(). Supposons que la Turquie joigne l’Union Européenne en 2026 :

# Création de l'objet Series
ligne_turquie = pd.Series(data = ['turquie', 'ankara', 83154997, np.datetime64('2026', 'Y')], 
                          index = df_europe.columns, name = 28)

# name c'est pour donner un name de colonne ou ID

# Affichage
print(ligne_turquie)
pays                turquie
capitale             ankara
population         83154997
date d'adhésion        2026
Name: 28, dtype: object
# en supposant un pays hors de l'europe
ligne_co = pd.Series(data = ['colombie', 'bogota', 8123213, np.datetime64('2022', 'Y')], 
                     index=df_europe.columns, name=29)
    
print(df_europe.columns)
Index(['pays', 'capitale', 'population', 'date d'adhésion'], dtype='object')
# Ajout de la ligne à l'objet DataFrame
df_europe = df_europe.append(ligne_turquie)

# Affichage des 2 dernières lignes
df_europe.tail(n = 2)
pays capitale population date d'adhésion
27 suède stockholm 9851017 1995-01-01
28 turquie ankara 83154997 2026-01-01
# Ajout de la ligne à l'objet DataFrame
df_europe = df_europe.append(ligne_co)

# Affichage des 2 dernières lignes
df_europe.tail(n = 2)
pays capitale population date d'adhésion
28 turquie ankara 83154997 2026-01-01
29 colombie bogota 8123213 2022-01-01

Plusieurs remarques :

  • Pour créer l’objet Series on a utilisé l’option index pour nommer les colonnes, et l’option name pour lui donner un nom

  • L’étiquette de la nouvelle ligne de l’objet DataFrame est le nom de l’objet Series

  • On aurait pu ignorer ce nom en utilisant l’option de la méthode append() : ignore_index = True

La méthode .drop() permet de supprimer des lignes :

# Supprimer la ligne avec l'étiquette 28
df_europe = df_europe.drop([28])

# Affichage des 2 dernières lignes
df_europe.tail(n = 2)
pays capitale population date d'adhésion
27 suède stockholm 9851017 1995-01-01
29 colombie bogota 8123213 2022-01-01
df_europe = df_europe.drop([29]) # remove the line i added

Il est beaucoup plus simple d’ajouter une colonne à un DataFrame. On peut le faire de la même manière que l’on ajoute une paire clé-valeur à un dictionnaire. Par exemple, ajoutons la colonne qui donne le nombre de sièges au parlement européen pour chaque pays de l’UE :

# Nombre de sièges au parlement
np_sieges = np.array([96, 18, 21, 17, 6, 11, 13, 54, 6, 13, 74, 21, 21, 11, 73, 8, 11, 6, 6, 26, 51, 21, 21, 32, 13, 8, 20])

# Ajout de la colonne
df_europe['sièges'] = np_sieges

# Affichage des 2 premières lignes
df_europe.head(n = 2)
pays capitale population date d'adhésion sièges
1 allemagne berlin 82162000 1957-01-01 96
2 autriche vienne 8700471 1995-01-01 18

Opérateurs arithmétiques et fonctions#

Il est possible d’utiliser les opérateurs arithmétiques usuels et les fonctions Numpy sur les colonnes d’un objet DataFrame. Par exemple, calculons le pourcentage de la population dans chaque pays par rapport à la population totale :

# Population totale
pop_tot = df_europe['population'].sum()

# Pourcentage de la population
pop_pourcentage = df_europe['population'] / pop_tot * 100

# Affichage
print(pop_pourcentage)
1     18.480761
2      1.957004
3      2.539435
4      1.609106
5      0.190813
6      0.942610
7      1.273044
8     10.445429
9      0.295996
10     1.214911
11    14.994249
12     2.427796
13     2.211178
14     1.047847
15    13.645548
16     0.442879
17     0.649726
18     0.129616
19     0.097711
20     3.819126
21     8.539993
22     2.326083
23     2.373886
24     4.444625
25     1.220531
26     0.464299
27     2.215797
Name: population, dtype: float64

Exercice#

Nous voulons connaître le poids de chaque pays au parlement par rapport à son nombre d’habitants.

  1. Calculer le nombre de sièges au parlement par habitant dans chaque pays, c’est-à-dire :

\[N_i = \frac{\text{nombre de sièges}}{\text{nombre d'habitants}}\]
  1. Normaliser le résultat et l’exprimer en pourcentage, c’est-à-dire :

\[\bar{N}_i = \frac{N_i}{\sum_i N_i}\times 100\]
  1. Ajouter une nouvelle colonne au DataFrame df_europe avec le nom 'poids' qui contient \(\bar{N}_i\)

  2. Afficher les colonnes 'pays' et 'poids' du DataFrame df_europe pour les 20 premières lignes

# 1
N_1 = df_europe['sièges'] / df_europe['population']

# 2  - normaliser
N_1 = ( N_1 / N_1.sum() ) * 100

# 3
df_europe['poids'] = N_1

# 4
print(df_europe[['pays','poids']].head(n=20))
          pays      poids
1    allemagne   1.370336
2     autriche   2.426367
3     belgique   2.181513
4     bulgarie   2.787018
5       chypre   8.295046
6      croatie   3.078478
7     danemark   2.693863
8      espagne   1.363776
9      estonie   5.347374
10    finlande   2.822763
11      france   1.301915
12       grèce   2.281827
13     hongrie   2.505365
14     irlande   2.769303
15      italie   1.411261
16    lettonie   4.765193
17    lituanie   4.466202
18  luxembourg  12.211466
19       malte  16.198887
20    pays-bas   1.795911

Trier un DataFrame#

Il est très facile de trier un objet DataFrame avec la méthode .sort_values(). Par exemple, on voit qu’en classant les pays d’abord par nombre de sièges croissant, puis, pour un même nombre de sièges, par poids décroissant, on déduit que plus le nombre de sièges et la population augmentent, plus le poids d’un pays au parlement diminue :

df_europe.sort_values(by = ['sièges', 'poids', 'population'], ascending = [False, False,False])
pays capitale population date d'adhésion sièges poids
1 allemagne berlin 82162000 1957-01-01 96 1.370336
11 france paris 66661621 1957-01-01 74 1.301915
15 italie rome 60665551 1957-01-01 73 1.411261
8 espagne madrid 46438422 1986-01-01 54 1.363776
21 pologne varsovie 37967209 2004-01-01 51 1.575391
24 roumanie bucarest 19759968 2007-01-01 32 1.899287
20 pays-bas amsterdam 16979120 1957-01-01 26 1.795911
13 hongrie budapest 9830485 2004-01-01 21 2.505365
22 portugal lisbonne 10341330 1986-01-01 21 2.381604
23 république tchèque prague 10553853 2004-01-01 21 2.333646
12 grèce athènes 10793526 1981-01-01 21 2.281827
3 belgique bruxelles 11289853 1957-01-01 21 2.181513
27 suède stockholm 9851017 1995-01-01 20 2.381089
2 autriche vienne 8700471 1995-01-01 18 2.426367
4 bulgarie sofia 7153784 2007-01-01 17 2.787018
10 finlande helsinki 5401267 1995-01-01 13 2.822763
25 slovaquie bratislava 5426252 2004-01-01 13 2.809766
7 danemark copenhague 5659715 1973-01-01 13 2.693863
17 lituanie vilnius 2888558 2004-01-01 11 4.466202
6 croatie zagreb 4190669 2013-01-01 11 3.078478
14 irlande dublin 4658530 1973-01-01 11 2.769303
16 lettonie riga 1968957 2004-01-01 8 4.765193
26 slovénie ljubljana 2064188 2004-01-01 8 4.545352
19 malte la valette 434403 2004-01-01 6 16.198887
18 luxembourg luxembourg 576249 1957-01-01 6 12.211466
5 chypre nicosie 848319 2004-01-01 6 8.295046
9 estonie tallinn 1315944 2004-01-01 6 5.347374
help(pd.DataFrame.sort_values)
Help on function sort_values in module pandas.core.frame:

sort_values(self, by, axis: 'Axis' = 0, ascending=True, inplace: 'bool' = False, kind: 'str' = 'quicksort', na_position: 'str' = 'last', ignore_index: 'bool' = False, key: 'ValueKeyFunc' = None)
    Sort by the values along either axis.
    
    Parameters
    ----------
            by : str or list of str
                Name or list of names to sort by.
    
                - if `axis` is 0 or `'index'` then `by` may contain index
                  levels and/or column labels.
                - if `axis` is 1 or `'columns'` then `by` may contain column
                  levels and/or index labels.
    axis : {0 or 'index', 1 or 'columns'}, default 0
         Axis to be sorted.
    ascending : bool or list of bool, default True
         Sort ascending vs. descending. Specify list for multiple sort
         orders.  If this is a list of bools, must match the length of
         the by.
    inplace : bool, default False
         If True, perform operation in-place.
    kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, default 'quicksort'
         Choice of sorting algorithm. See also :func:`numpy.sort` for more
         information. `mergesort` and `stable` are the only stable algorithms. For
         DataFrames, this option is only applied when sorting on a single
         column or label.
    na_position : {'first', 'last'}, default 'last'
         Puts NaNs at the beginning if `first`; `last` puts NaNs at the
         end.
    ignore_index : bool, default False
         If True, the resulting axis will be labeled 0, 1, …, n - 1.
    
         .. versionadded:: 1.0.0
    
    key : callable, optional
        Apply the key function to the values
        before sorting. This is similar to the `key` argument in the
        builtin :meth:`sorted` function, with the notable difference that
        this `key` function should be *vectorized*. It should expect a
        ``Series`` and return a Series with the same shape as the input.
        It will be applied to each column in `by` independently.
    
        .. versionadded:: 1.1.0
    
    Returns
    -------
    DataFrame or None
        DataFrame with sorted values or None if ``inplace=True``.
    
    See Also
    --------
    DataFrame.sort_index : Sort a DataFrame by the index.
    Series.sort_values : Similar method for a Series.
    
    Examples
    --------
    >>> df = pd.DataFrame({
    ...     'col1': ['A', 'A', 'B', np.nan, 'D', 'C'],
    ...     'col2': [2, 1, 9, 8, 7, 4],
    ...     'col3': [0, 1, 9, 4, 2, 3],
    ...     'col4': ['a', 'B', 'c', 'D', 'e', 'F']
    ... })
    >>> df
      col1  col2  col3 col4
    0    A     2     0    a
    1    A     1     1    B
    2    B     9     9    c
    3  NaN     8     4    D
    4    D     7     2    e
    5    C     4     3    F
    
    Sort by col1
    
    >>> df.sort_values(by=['col1'])
      col1  col2  col3 col4
    0    A     2     0    a
    1    A     1     1    B
    2    B     9     9    c
    5    C     4     3    F
    4    D     7     2    e
    3  NaN     8     4    D
    
    Sort by multiple columns
    
    >>> df.sort_values(by=['col1', 'col2'])
      col1  col2  col3 col4
    1    A     1     1    B
    0    A     2     0    a
    2    B     9     9    c
    5    C     4     3    F
    4    D     7     2    e
    3  NaN     8     4    D
    
    Sort Descending
    
    >>> df.sort_values(by='col1', ascending=False)
      col1  col2  col3 col4
    4    D     7     2    e
    5    C     4     3    F
    2    B     9     9    c
    0    A     2     0    a
    1    A     1     1    B
    3  NaN     8     4    D
    
    Putting NAs first
    
    >>> df.sort_values(by='col1', ascending=False, na_position='first')
      col1  col2  col3 col4
    3  NaN     8     4    D
    4    D     7     2    e
    5    C     4     3    F
    2    B     9     9    c
    0    A     2     0    a
    1    A     1     1    B
    
    Sorting with a key function
    
    >>> df.sort_values(by='col4', key=lambda col: col.str.lower())
       col1  col2  col3 col4
    0    A     2     0    a
    1    A     1     1    B
    2    B     9     9    c
    3  NaN     8     4    D
    4    D     7     2    e
    5    C     4     3    F
    
    Natural sort with the key argument,
    using the `natsort <https://github.com/SethMMorton/natsort>` package.
    
    >>> df = pd.DataFrame({
    ...    "time": ['0hr', '128hr', '72hr', '48hr', '96hr'],
    ...    "value": [10, 20, 30, 40, 50]
    ... })
    >>> df
        time  value
    0    0hr     10
    1  128hr     20
    2   72hr     30
    3   48hr     40
    4   96hr     50
    >>> from natsort import index_natsorted
    >>> df.sort_values(
    ...    by="time",
    ...    key=lambda x: np.argsort(index_natsorted(df["time"]))
    ... )
        time  value
    0    0hr     10
    3   48hr     40
    2   72hr     30
    4   96hr     50
    1  128hr     20

Sauvegarder un DataFrame#

Il est possible de sauver un objet DataFrame sous la forme d’un fichier csv. C’est un format pratique qui peut être lu par la plupart des tableurs comme LibreOffice Calc ou Microsoft Excel. Il faut utiliser la métode .to_csv() :

df_europe.to_csv("europe-ca.csv")

Cette méthode crée un fichier nommé data.csv dans le répertoire de travail (allez vérifier !), avec le contenu du DataFrame :

,pays,capitale,population,date d'adhésion,sièges,poids
1,allemagne,berlin,82162000,1957-01-01,96,1.3703356988657123
2,autriche,vienne,8700471,1995-01-01,18,2.4263669538020842
3,belgique,bruxelles,11289853,1957-01-01,21,2.1815127149779783
4,bulgarie,sofia,7153784,2007-01-01,17,2.7870184226008328
5,chypre,nicosie,848319,2004-01-01,6,8.295045974023676
6,croatie,zagreb,4190669,2013-01-01,11,3.078478088741746
7,danemark,copenhague,5659715,1973-01-01,13,2.6938631589897866
8,espagne,madrid,46438422,1986-01-01,54,1.363776011827881
9,estonie,tallinn,1315944,2004-01-01,6,5.347374284648732
10,finlande,helsinki,5401267,1995-01-01,13,2.822763201464005
11,france,paris,66661621,1957-01-01,74,1.301914879970682
12,grèce,athènes,10793526,1981-01-01,21,2.28182689046492
13,hongrie,budapest,9830485,2004-01-01,21,2.5053654900782893
14,irlande,dublin,4658530,1973-01-01,11,2.7693033411117423
15,italie,rome,60665551,1957-01-01,73,1.4112613727889787
16,lettonie,riga,1968957,2004-01-01,8,4.765193013788716
17,lituanie,vilnius,2888558,2004-01-01,11,4.466201715066578
18,luxembourg,luxembourg,576249,1957-01-01,6,12.211466060050068
19,malte,la valette,434403,2004-01-01,6,16.198886991198936
20,pays-bas,amsterdam,16979120,1957-01-01,26,1.7959114169499812
21,pologne,varsovie,37967209,2004-01-01,51,1.5753905797479404
22,portugal,lisbonne,10341330,1986-01-01,21,2.381604481215885
23,république tchèque,prague,10553853,2004-01-01,21,2.3336460977552242
24,roumanie,bucarest,19759968,2007-01-01,32,1.8992865050895604
25,slovaquie,bratislava,5426252,2004-01-01,13,2.8097658805528902
26,slovénie,ljubljana,2064188,2004-01-01,8,4.545351557537583
27,suède,stockholm,9851017,1995-01-01,20,2.381089216689604

Il est alors possible, plus tard, de charger le contenu du fichier csv avec la méthode .read_csv() :

df_europe_from_csv = pd.read_csv("europe-ca.csv", index_col = 0, encoding = 'utf-8')

L’option encoding peut être nécessaire sur certains ordinateurs, pas sur d’autres.

Un problème de sauvegarder en csv est que si une des colonnes contient des objets python, il peuvent être convertis en un autre type au moment de l’écriture et de la lecture. Dans l’exemple ci-dessus, la colonne date d'adhésion n’est plus un objet datetime64 au moment de la lecture : il a été converti en objet str.

A = df_europe_from_csv["date d'adhésion"][1]
print(A)
print(type(A))
1957-01-01
<class 'str'>

Une façon de garder toutes les propriétés des objets python est de les sauver dans un format que l’on appelle pickle :

# Sauvegarde d'un DataFrame dans un fichier pickle
df_europe.to_pickle('europe.pkl')

# Lecture du fichier pickle
df_europe_from_pickle = pd.read_pickle('./europe.pkl')

On voit alors que les dates sont restées des objets datetime64 :

df_europe_from_pickle["date d'adhésion"].head(n = 2)
1   1957-01-01
2   1995-01-01
Name: date d'adhésion, dtype: datetime64[ns]