Chapter 4 Data manipulation avec Pandas & Scipy

4.1 Pandas

import pandas as pd
import warnings
warnings.filterwarnings('ignore')
pd.set_option('display.max_columns',10)

4.1.1 Lecture de données

data = pd.read_csv("/Users/abdoul_aziz_berrada/Documents/Cours/Python/globalterrorismdb_0718dist.csv", encoding='iso-8859-1', low_memory=False)

4.1.2 Affichage des données

data.head()
##         eventid  iyear  imonth  iday approxdate  ...  INT_LOG INT_IDEO   
## 0  197000000001   1970       7     2        NaN  ...        0        0  \
## 1  197000000002   1970       0     0        NaN  ...        0        1   
## 2  197001000001   1970       1     0        NaN  ...       -9       -9   
## 3  197001000002   1970       1     0        NaN  ...       -9       -9   
## 4  197001000003   1970       1     0        NaN  ...       -9       -9   
## 
##    INT_MISC INT_ANY  related  
## 0         0       0      NaN  
## 1         1       1      NaN  
## 2         1       1      NaN  
## 3         1       1      NaN  
## 4         1       1      NaN  
## 
## [5 rows x 135 columns]
data.tail()
##              eventid  iyear  imonth  iday approxdate  ...  INT_LOG INT_IDEO   
## 181686  201712310022   2017      12    31        NaN  ...        0        0  \
## 181687  201712310029   2017      12    31        NaN  ...       -9       -9   
## 181688  201712310030   2017      12    31        NaN  ...        0        0   
## 181689  201712310031   2017      12    31        NaN  ...       -9       -9   
## 181690  201712310032   2017      12    31        NaN  ...       -9       -9   
## 
##         INT_MISC INT_ANY  related  
## 181686         0       0      NaN  
## 181687         1       1      NaN  
## 181688         0       0      NaN  
## 181689         0      -9      NaN  
## 181690         0      -9      NaN  
## 
## [5 rows x 135 columns]
data.shape
## (181691, 135)
print(f""" La table contient {data.shape[0]} lignes et {data.shape[1]} colonnes.""")
##  La table contient 181691 lignes et 135 colonnes.
data.info()
## <class 'pandas.core.frame.DataFrame'>
## RangeIndex: 181691 entries, 0 to 181690
## Columns: 135 entries, eventid to related
## dtypes: float64(55), int64(22), object(58)
## memory usage: 187.1+ MB
list(data.columns)
## ['eventid', 'iyear', 'imonth', 'iday', 'approxdate', 'extended', 'resolution', 'country', 'country_txt', 'region', 'region_txt', 'provstate', 'city', 'latitude', 'longitude', 'specificity', 'vicinity', 'location', 'summary', 'crit1', 'crit2', 'crit3', 'doubtterr', 'alternative', 'alternative_txt', 'multiple', 'success', 'suicide', 'attacktype1', 'attacktype1_txt', 'attacktype2', 'attacktype2_txt', 'attacktype3', 'attacktype3_txt', 'targtype1', 'targtype1_txt', 'targsubtype1', 'targsubtype1_txt', 'corp1', 'target1', 'natlty1', 'natlty1_txt', 'targtype2', 'targtype2_txt', 'targsubtype2', 'targsubtype2_txt', 'corp2', 'target2', 'natlty2', 'natlty2_txt', 'targtype3', 'targtype3_txt', 'targsubtype3', 'targsubtype3_txt', 'corp3', 'target3', 'natlty3', 'natlty3_txt', 'gname', 'gsubname', 'gname2', 'gsubname2', 'gname3', 'gsubname3', 'motive', 'guncertain1', 'guncertain2', 'guncertain3', 'individual', 'nperps', 'nperpcap', 'claimed', 'claimmode', 'claimmode_txt', 'claim2', 'claimmode2', 'claimmode2_txt', 'claim3', 'claimmode3', 'claimmode3_txt', 'compclaim', 'weaptype1', 'weaptype1_txt', 'weapsubtype1', 'weapsubtype1_txt', 'weaptype2', 'weaptype2_txt', 'weapsubtype2', 'weapsubtype2_txt', 'weaptype3', 'weaptype3_txt', 'weapsubtype3', 'weapsubtype3_txt', 'weaptype4', 'weaptype4_txt', 'weapsubtype4', 'weapsubtype4_txt', 'weapdetail', 'nkill', 'nkillus', 'nkillter', 'nwound', 'nwoundus', 'nwoundte', 'property', 'propextent', 'propextent_txt', 'propvalue', 'propcomment', 'ishostkid', 'nhostkid', 'nhostkidus', 'nhours', 'ndays', 'divert', 'kidhijcountry', 'ransom', 'ransomamt', 'ransomamtus', 'ransompaid', 'ransompaidus', 'ransomnote', 'hostkidoutcome', 'hostkidoutcome_txt', 'nreleased', 'addnotes', 'scite1', 'scite2', 'scite3', 'dbsource', 'INT_LOG', 'INT_IDEO', 'INT_MISC', 'INT_ANY', 'related']

4.1.3 Sélection de données

4.1.3.1 Par colonnes

On veut garder uniquement les colonnes suivantes : ‘iyear’, ‘imonth’, ‘iday’, ‘extended’, ‘country_txt’, ‘region_txt’, ‘city’,‘multiple’, ‘success’, ‘suicide’, ‘attacktype1_txt’, ‘targtype1_txt’, ‘targsubtype1_txt’,
‘natlty1_txt’, ‘gname’, ‘weaptype1_txt’, ‘weapsubtype1_txt’, ‘nkill’, ‘nwound’

On a alors 2 solutions, soit on supprime celles dont on a pas besoin, soit on sélectionne que celles dont a besoin.

  • La solution de suppression se fait pas la fonction drop(columns = liste_de_colonnes_a_supprimer, axis = 0). On met axis = 0 pour dire qu’on supprime des colonnes.
cols_a_supprimer = [ "approxdate","resolution","provstate","specificity","vicinity","location","alternative","attacktype1",
                     "attacktype2", "attacktype2_txt", "attacktype3", "attacktype3_txt",
                     "corp1", "targtype2", "targtype2_txt","targsubtype2","targsubtype2_txt", "corp2", "target2", "natlty2",
                     "natlty2_txt", "targtype3", "targtype3_txt", "targsubtype3","targsubtype3_txt", "corp3", "target3", "natlty3",
                     "natlty3_txt", "gsubname", "gname2", "gsubname2", "gname3", "gsubname3", "guncertain2", "guncertain3",
                     "individual", "nperpcap", "claimmode", "claim2", "claimmode2", "claimmode2_txt", "claim3", "claimmode3", "claimmode3_txt",
                     "compclaim", "weaptype2", "weaptype2_txt", "weapsubtype2", "weapsubtype2_txt",
                     "weaptype3", "weaptype3_txt", "weapsubtype3", "weapsubtype3_txt", 
                     "weaptype4", "weaptype4_txt", "weapsubtype4", "weapsubtype4_txt", "nkillus", "nkillter",
                     "nwoundus", "nwoundte","propextent", "nhostkidus", "nhours", "ndays", "divert", "kidhijcountry",
                     "ransom", "ransomamt", "ransomamtus", "ransompaid", "ransompaidus", "hostkidoutcome", "hostkidoutcome_txt",
                     "addnotes", "scite1", "scite2", "scite3", "dbsource","INT_LOG", "INT_IDEO", "INT_MISC", "INT_ANY",    
                     "related","eventid","summary","alternative_txt","nperps","claimed","claimmode_txt","weapdetail",
                     "propextent_txt","propvalue", "propcomment", "nhostkid", "ransomnote","nreleased", "doubtterr",
                     "motive", "property", 'country', 'target1', 'natlty1', 'weapsubtype1', 'targsubtype1', 'targtype1',
                     'region', 'weaptype1', 'ishostkid', 'latitude', 'longitude', 'crit1', 'crit2', 'crit3', 'guncertain1']
                      
df = data.drop(columns=cols_a_supprimer, axis = 0) 
                       

print(f"""Les colonnes de la table sont : \n {list(df.columns)}""")
## Les colonnes de la table sont : 
##  ['iyear', 'imonth', 'iday', 'extended', 'country_txt', 'region_txt', 'city', 'multiple', 'success', 'suicide', 'attacktype1_txt', 'targtype1_txt', 'targsubtype1_txt', 'natlty1_txt', 'gname', 'weaptype1_txt', 'weapsubtype1_txt', 'nkill', 'nwound']
  • La sélection de colonnes pertinentes Pour sélectionner des colonnes dans un dataframe, il suffit d’appliquer la syntaxe : data[liste_colonnes_a_selectionner]
cols_a_selectionner = ['iyear', 'country_txt','city', 'success', 'suicide', 
                      'attacktype1_txt', 'targtype1_txt', 'ndays',
                      'natlty1_txt', 'gname', 'weaptype1_txt', 'nkill', 'nwound']

df = data[cols_a_selectionner]
print(f"""Les colonnes de la table sont : \n {list(df.columns)}""")
## Les colonnes de la table sont : 
##  ['iyear', 'country_txt', 'city', 'success', 'suicide', 'attacktype1_txt', 'targtype1_txt', 'ndays', 'natlty1_txt', 'gname', 'weaptype1_txt', 'nkill', 'nwound']

4.1.4 Statistiques descriptives

4.1.4.1 Types des colonnes

Pour commencer dans les statistiques descriptives, une étape importante est de connaître le type des colonnes qu’on traite. En effet, certaines colonnes peuvent ne pas avoir le bon type, et en fonction du type de la variable certaines manipulations peuvent ne pas être adaptées.

L’attribut dtypes permet de connaitre le type des variables.

Dans l’exemple suivant on va utiliser cet attribut puis on va appliquer la fonction sort_values() pour trier les types par ordre.

df.dtypes.sort_values() # On applique l'attribut 
## iyear                int64
## success              int64
## suicide              int64
## ndays              float64
## nkill              float64
## nwound             float64
## country_txt         object
## city                object
## attacktype1_txt     object
## targtype1_txt       object
## natlty1_txt         object
## gname               object
## weaptype1_txt       object
## dtype: object

On voit par exemple que iyear est au format int64, ce qui signifie que ses valeurs sont des entiers naturels; nkill est une variable de type float, ses valeurs sont décimales. Et targtype1_txt est de type object, ses valeurs sont des chaînes de caractères.

df[['iyear', 'success', 'suicide']]
##         iyear  success  suicide
## 0        1970        1        0
## 1        1970        1        0
## 2        1970        1        0
## 3        1970        1        0
## 4        1970        1        0
## ...       ...      ...      ...
## 181686   2017        1        0
## 181687   2017        1        0
## 181688   2017        1        0
## 181689   2017        0        0
## 181690   2017        0        0
## 
## [181691 rows x 3 columns]

4.1.4.2 Mise des colonnes au bon format

On voit que certaines variables se sont pas au bon format, il s’agit alors de success* et suicide que l’on va mettre au format object. Ce choix se justifie par le fait que success et suicide sont des variables binaires, donc discrêtes, le meilleur choix est de les mettre en object.

Cette opération est faite en appliquant la fonction astype(type_de_destination)**.

La syntaxe est la suivante : data[col] = data[col].astype(type_de_destination)

df['success'] = df['success'].astype(str)
df['suicide'] = df['suicide'].astype(str)


df.dtypes.sort_values() # On vérifie de nouveau les types
## iyear                int64
## ndays              float64
## nkill              float64
## nwound             float64
## country_txt         object
## city                object
## success             object
## suicide             object
## attacktype1_txt     object
## targtype1_txt       object
## natlty1_txt         object
## gname               object
## weaptype1_txt       object
## dtype: object
#import matplotlib as plt
#df.dtypes.value_counts().plot.pie()

4.1.4.3 Nombre de valeurs manquantes

Les données réelles peuvent non seulement présenter des lacunes, mais aussi des valeurs erronées en raison d’un équipement de mesure défectueux, par exemple. Dans pandas, les valeurs numériques manquantes seront désignées par NaN ou par NaT (pour les dates).

La fonction isna() (ou isnull()) nous permet de savoir si une observation est une valeur manquante, en appliquant à la suite la fonction sum(),on a le nombre de valeurs manquantes de chaque variable.

df.isna().head(10) # pour savoir si on a des valeurs manquantes
##    iyear  country_txt   city  success  suicide  ...  natlty1_txt  gname   
## 0  False        False  False    False    False  ...        False  False  \
## 1  False        False  False    False    False  ...        False  False   
## 2  False        False  False    False    False  ...        False  False   
## 3  False        False  False    False    False  ...        False  False   
## 4  False        False  False    False    False  ...        False  False   
## 5  False        False  False    False    False  ...        False  False   
## 6  False        False  False    False    False  ...        False  False   
## 7  False        False  False    False    False  ...        False  False   
## 8  False        False  False    False    False  ...        False  False   
## 9  False        False  False    False    False  ...        False  False   
## 
##    weaptype1_txt  nkill  nwound  
## 0          False  False   False  
## 1          False  False   False  
## 2          False  False   False  
## 3          False   True    True  
## 4          False   True    True  
## 5          False  False   False  
## 6          False  False   False  
## 7          False  False   False  
## 8          False  False   False  
## 9          False  False   False  
## 
## [10 rows x 13 columns]

Lorsque l’on a True ca veut dire que l’observation est une valeur manquante. On va vérifier en affichant le vrai dataframe.

df.head(10)
##    iyear         country_txt           city success suicide  ...   
## 0   1970  Dominican Republic  Santo Domingo       1       0  ...  \
## 1   1970              Mexico    Mexico city       1       0  ...   
## 2   1970         Philippines        Unknown       1       0  ...   
## 3   1970              Greece         Athens       1       0  ...   
## 4   1970               Japan        Fukouka       1       0  ...   
## 5   1970       United States          Cairo       1       0  ...   
## 6   1970             Uruguay     Montevideo       0       0  ...   
## 7   1970       United States        Oakland       1       0  ...   
## 8   1970       United States        Madison       1       0  ...   
## 9   1970       United States        Madison       1       0  ...   
## 
##           natlty1_txt                               gname  weaptype1_txt   
## 0  Dominican Republic                              MANO-D        Unknown  \
## 1             Belgium  23rd of September Communist League        Unknown   
## 2       United States                             Unknown        Unknown   
## 3       United States                             Unknown     Explosives   
## 4       United States                             Unknown     Incendiary   
## 5       United States                  Black Nationalists       Firearms   
## 6             Uruguay                 Tupamaros (Uruguay)       Firearms   
## 7       United States                             Unknown     Explosives   
## 8       United States                     New Year's Gang     Incendiary   
## 9       United States                     New Year's Gang     Incendiary   
## 
##   nkill nwound  
## 0   1.0    0.0  
## 1   0.0    0.0  
## 2   1.0    0.0  
## 3   NaN    NaN  
## 4   NaN    NaN  
## 5   0.0    0.0  
## 6   0.0    0.0  
## 7   0.0    0.0  
## 8   0.0    0.0  
## 9   0.0    0.0  
## 
## [10 rows x 13 columns]

On voit effectivement que la ligne n°4 des variables weapsubtype1_txt, nkill, nwound sont effectivement des NaN.

On va maintenant compter le nombre de valeurs manquantes par variable en appliquant la fonction sum()

df.isna().sum() #pour pour avoir le nombre de valeurs manquantes
## iyear                   0
## country_txt             0
## city                  435
## success                 0
## suicide                 0
## attacktype1_txt         0
## targtype1_txt           0
## ndays              173567
## natlty1_txt          1559
## gname                   0
## weaptype1_txt           0
## nkill               10313
## nwound              16311
## dtype: int64

Dans l’exemple suivant, on va appliquer ces 2 fonctions mais on fait 2 manipulations en plus :

  • On applique aussi la fonction sort_values() avec l’argument ascending = False pour faire un tri du nombre de valeurs manquantes par ordre décroissant. Il faut mettre True à la place de False si on veut faire un tri croissant.

  • On divise par df.shape[0] qui est le nombre d’observations de la table. Cette opération nous permet d’avoir le pourcentage de valeurs manquantes de la table qui est plus pertinent que le nombre de valeurs manquantes.

# df.isna() : pour savoir si on a des valeurs manquantes
# df.isna().sum() : pour pour avoir le nombre de valeurs manquantes
# df.isna().sum().sort_values(ascending = False) : nombre de valeurs manquantes 
                                                   # par ordre décroissant 

df.isna().sum().sort_values(ascending = False) / df.shape[0]  # pourcentage de valeurs manquantes
                                                              # par ordre décroissant
## ndays              0.955287
## nwound             0.089773
## nkill              0.056761
## natlty1_txt        0.008581
## city               0.002394
## iyear              0.000000
## country_txt        0.000000
## success            0.000000
## suicide            0.000000
## attacktype1_txt    0.000000
## targtype1_txt      0.000000
## gname              0.000000
## weaptype1_txt      0.000000
## dtype: float64

On voit alors que la variable qui a le plus de valeurs manquantes est nwound avec 8%.

4.1.4.4 Stats de base

Les statistiques de bases sont différentes selon le type de variables, quand on travaille avec des données quantitatives (continues généralement), on veut avoir des informations sur la distribution de la variable qui sont la moyenne, médiane, variance, écart type, les quantiles etc or quand on est avec des données qualitatives, on a besoin du mode, du nombre de valeurs uniques etc.

Ces informations sont données par la fonction describe(). Mais avant il est recommandé de sélectionner le type de colonnes par la fonction select_dtypes([liste_type_colonne])

Dans l’exemple suivant on va appliquer ces fonctions ppur avoir les stats descriptives d’abord des quantitatives (int et float) et

df.select_dtypes(['float', 'int']).describe() # pour les variables quantitatives
##                iyear        ndays          nkill         nwound
## count  181691.000000  8124.000000  171378.000000  165380.000000
## mean     2002.638997   -32.516371       2.403272       3.167668
## std        13.259430   121.209205      11.545741      35.949392
## min      1970.000000   -99.000000       0.000000       0.000000
## 25%      1991.000000   -99.000000       0.000000       0.000000
## 50%      2009.000000   -99.000000       0.000000       0.000000
## 75%      2014.000000     4.000000       2.000000       2.000000
## max      2017.000000  2454.000000    1570.000000    8191.000000

Interpréation : On dénombre respectivement 171378 et 165380 instances non nulles des variables nkill et nwound. Le nombre de morts moyen des attentats est de 2.4 et celui du nombre de blessés de 3.16. On peut peut qu’en moyenne un attentat terroriste fait plus de blessés que de morts. Ensuite l’attentat ayant fait le plus de blessés en a fait 8191 et celui qui a fait le plus de morts en a fait 1570. De plus on voit aussi 50% des attentats font 0 mort et 0 blessé (médiane) et 75% d’entre eux font au plus 2 morts et 2 blessés.

df.select_dtypes(['object']).describe() # pour les variables qualitatives
##        country_txt     city success suicide    attacktype1_txt   
## count       181691   181256  181691  181691             181691  \
## unique         205    36673       2       2                  9   
## top           Iraq  Unknown       1       0  Bombing/Explosion   
## freq         24636     9775  161632  175058              88255   
## 
##                       targtype1_txt natlty1_txt    gname weaptype1_txt  
## count                        181691      180132   181691        181691  
## unique                           22         215     3537            12  
## top     Private Citizens & Property        Iraq  Unknown    Explosives  
## freq                          43511       24113    82782         92426

Interprétation :

L’année avec le plus d’attentats terroristes est l’année 2014 (top), avec 16903 attentats (freq) et on a 47 ans d’historique dans nos données (unique). Le pays avec le plus d’attentats terroristes est Iraq avec 24636 attentats. On a 205 pays dans la table.

4.1.4.5 Nombre de valeurs uniques

On peut connaitre le nombre de valeurs uniques comme par exemple le nombre d’années que comptient notre table à travers les informations issues de la fonction describe() mais de manière plus spécifique, la fonction nunique() est plus directe et nous donne juste ce dont on a besoin.

# Faire df['iyear'].nunique() pour la variable iyear seulement
df.select_dtypes(['object']).nunique()
## country_txt          205
## city               36673
## success                2
## suicide                2
## attacktype1_txt        9
## targtype1_txt         22
## natlty1_txt          215
## gname               3537
## weaptype1_txt         12
## dtype: int64
for col in df.select_dtypes(['object']).columns :
  print(f""" Le nombre de valeurs uniques de la variable {col} est {df[col].nunique()}""")
##  Le nombre de valeurs uniques de la variable country_txt est 205
##  Le nombre de valeurs uniques de la variable city est 36673
##  Le nombre de valeurs uniques de la variable success est 2
##  Le nombre de valeurs uniques de la variable suicide est 2
##  Le nombre de valeurs uniques de la variable attacktype1_txt est 9
##  Le nombre de valeurs uniques de la variable targtype1_txt est 22
##  Le nombre de valeurs uniques de la variable natlty1_txt est 215
##  Le nombre de valeurs uniques de la variable gname est 3537
##  Le nombre de valeurs uniques de la variable weaptype1_txt est 12

Il en est de même pour la moyenne avec la fonction mean(axis = 0), médiane median(axis = 0), maximum max(axis = 0), minimum min(axis = 0) etc

df.select_dtypes(['float', 'int']).max(axis = 0)
## iyear     2017.0
## ndays     2454.0
## nkill     1570.0
## nwound    8191.0
## dtype: float64

4.1.4.6 Proportion de chaque classe

Si on veut connaître le nombre d’occurrences de chaque classe dans une variable qualitative, il faut appliquer la fonction value_counts(). Lorsque l’on lui donne l’argument normalize==True, on obtient les proportions.

Dans l’exemple suivant on cherche les proportions de chaque type d’armes et d’attaque

# on définit les colonnes qui nous intéressent
colonnes_prop = ['attacktype1_txt', 'weaptype1_txt'] 

# On fait une boucle qui va nous donner les proportions pour chaque variable 
for col in colonnes_prop:
  df[col].value_counts(normalize = True)
  print("\n") 
## attacktype1_txt
## Bombing/Explosion                      0.485742
## Armed Assault                          0.234844
## Assassination                          0.106290
## Hostage Taking (Kidnapping)            0.061412
## Facility/Infrastructure Attack         0.056998
## Unknown                                0.040046
## Unarmed Assault                        0.005586
## Hostage Taking (Barricade Incident)    0.005454
## Hijacking                              0.003627
## Name: proportion, dtype: float64
## 
## 
## weaptype1_txt
## Explosives                                                                     0.508699
## Firearms                                                                       0.322107
## Unknown                                                                        0.083422
## Incendiary                                                                     0.061285
## Melee                                                                          0.020117
## Chemical                                                                       0.001767
## Sabotage Equipment                                                             0.000776
## Vehicle (not to include vehicle-borne explosives, i.e., car or truck bombs)    0.000749
## Other                                                                          0.000627
## Biological                                                                     0.000193
## Fake Weapons                                                                   0.000182
## Radiological                                                                   0.000077
## Name: proportion, dtype: float64

On voit que 48% des attaques sont des explosions, 23% des assauts armés, 10% des assassinats etc. 50% des armes utilisés sont des explosifs et 32% des armes à feu.

4.1.4.7 Corrélations

Pour voir la corrélation entre des variables continues, on utilise la fonction corr().

df.select_dtypes(['float']).corr()
##            ndays     nkill    nwound
## ndays   1.000000 -0.040156 -0.028855
## nkill  -0.040156  1.000000  0.534375
## nwound -0.028855  0.534375  1.000000

Il existe une corrélation de -2% entre ndays et nwound, -4% entre nwound et ndays et 53% entre nwound et nkill.

4.1.4.8

4.1.4.9

4.1.4.10

4.1.4.11

4.1.5 Filtre des données

4.1.6 Trie des données

Pour filtrer des données dans un dataframe, on crée des tuples contenant les conditions à respecter, chaque condition est dans un tuple et tous les tuples sont séparés par & (et) si ont veut une intersection des conditions ou OR (ou) pour créer une union des conditions.

Une fois le filtre crée, il suffit de créer notre table filtrée avec la syntaxe data[filtre].

Dans l’exemple suivant on va sélectionner dans notre table les attentats terroristes qui se sont passés au Sénégal et qui sont survenus après 2010.

filtre = (df["country_txt"]=="Senegal") & (df['iyear']>2010) # Création du filtre
df[filtre][['iyear', 'country_txt', 'city', 'success', 'nwound', 'nkill']].head(20) # Création de la table filtré et 
                    # affichage des 20 premières lignes
##         iyear country_txt                   city success  nwound  nkill
## 100452   2011     Senegal                Unknown       1     0.0    3.0
## 104161   2011     Senegal                Diagnon       1     0.0   11.0
## 104560   2011     Senegal                 Kabeum       1     2.0    NaN
## 104646   2011     Senegal                Unknown       1     4.0    7.0
## 104805   2012     Senegal               Affiniam       1     6.0    1.0
## 105031   2012     Senegal                  Baila       1     0.0    0.0
## 105204   2012     Senegal                Bignona       1    12.0    5.0
## 105457   2012     Senegal                Unknown       1     3.0    4.0
## 105758   2012     Senegal                Unknown       1     4.0    1.0
## 106104   2012     Senegal            Sare Ndiaye       1     3.0    1.0
## 106306   2012     Senegal                Unknown       1     4.0    2.0
## 106503   2012     Senegal                Bignona       1     0.0    0.0
## 106660   2012     Senegal  Boutoupa-Camaracounda       1     4.0    0.0
## 108099   2012     Senegal                   Efok       1     1.0    2.0
## 109163   2012     Senegal                  Emaye       1     2.0    NaN
## 110193   2012     Senegal             Sjibidione       1     1.0    0.0
## 114138   2013     Senegal             Kafountine       1     1.0    5.0
## 114313   2013     Senegal                Unknown       1     0.0    2.0
## 116685   2013     Senegal                 Kaylou       1     0.0    0.0
## 135366   2014     Senegal                Badiana       1     0.0    0.0

4.1.7 loc et iloc

4.1.8 Nettoyage des données

4.1.8.1 Valeurs manquantes

4.1.8.2 Renommer des colonnes

4.1.8.3 Mise de colonnes au bon format

4.1.8.4 Gestion des valeurs extrêmes

4.1.9 Jointures

4.1.9.1 Jointures horizontales

On va créer 2 dataframes pour faire les exemples suivant.

#df12 = pd.concat([df1, df2], axis = 0)

4.1.9.2 Jointures verticales

Lorsque l’on veut joindre des tables verticalement, c’est à dire créer ajouter des colonnes supplémentaires à un dataframe de base, on utilise la fonction merge().

Cette fonction prend principalement 5 arguments :

  • right : qui est le dataframe de droite à joindre à celui de gauche
  • how : qui est le type de jointure à faire,
    • inner pour une jointure
    • right pour une jointure à droite
    • left pour une jointure à gauche
  • left_on : qui est la clé de jointure issue de la table de gauche,
  • right_on : qui est la clé de jointure de la table de droite

On va créer 2 dataframes pour faire les exemples suivant.

#df2 = pd.merge(df22, how = 'inner', left_on = '', right_on = '', axis = 1)
#df2 = pd.merge(df22, how = 'inner', left_on = '', right_on = '', axis = 1)

4.1.10 Comment répondre à une question avec pandas ?

On va essayer de répondre à des questions sur le

4.2 Scipy