Chapter 4 Data manipulation avec Pandas & Scipy
4.1 Pandas
import pandas as pd
import warnings
'ignore')
warnings.filterwarnings('display.max_columns',10) pd.set_option(
4.1.1 Lecture de données
= pd.read_csv("/Users/abdoul_aziz_berrada/Documents/Cours/Python/globalterrorismdb_0718dist.csv", encoding='iso-8859-1', low_memory=False) data
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.
= [ "approxdate","resolution","provstate","specificity","vicinity","location","alternative","attacktype1",
cols_a_supprimer "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']
= data.drop(columns=cols_a_supprimer, axis = 0)
df
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]
= ['iyear', 'country_txt','city', 'success', 'suicide',
cols_a_selectionner 'attacktype1_txt', 'targtype1_txt', 'ndays',
'natlty1_txt', 'gname', 'weaptype1_txt', 'nkill', 'nwound']
= data[cols_a_selectionner]
df 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.
# On applique l'attribut df.dtypes.sort_values()
## 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.
'iyear', 'success', 'suicide']] df[[
## 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)
'success'] = df['success'].astype(str)
df['suicide'] = df['suicide'].astype(str)
df[
# On vérifie de nouveau les types df.dtypes.sort_values()
## 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.
10) # pour savoir si on a des valeurs manquantes df.isna().head(
## 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.
10) df.head(
## 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()
sum() #pour pour avoir le nombre de valeurs manquantes df.isna().
## 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
sum().sort_values(ascending = False) / df.shape[0] # pourcentage de valeurs manquantes
df.isna().# 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
'float', 'int']).describe() # pour les variables quantitatives df.select_dtypes([
## 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.
'object']).describe() # pour les variables qualitatives df.select_dtypes([
## 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
'object']).nunique() df.select_dtypes([
## 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
'float', 'int']).max(axis = 0) df.select_dtypes([
## 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
= ['attacktype1_txt', 'weaptype1_txt']
colonnes_prop
# On fait une boucle qui va nous donner les proportions pour chaque variable
for col in colonnes_prop:
= True)
df[col].value_counts(normalize 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().
'float']).corr() df.select_dtypes([
## 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.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.
= (df["country_txt"]=="Senegal") & (df['iyear']>2010) # Création du filtre
filtre 'iyear', 'country_txt', 'city', 'success', 'nwound', 'nkill']].head(20) # Création de la table filtré et
df[filtre][[# 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.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