Produisez une étude de marché avec Python¶
Notebook 1 : Préparation, Nettoyage et Analyse exploratoire des données¶
1) Préparation et importation des données¶
import numpy as np
import pandas as pd
2 fichiers csv bruts ont été fournis :
population = pd.read_csv('Population_2000_2018.csv')
disponibiliteAlimentaire = pd.read_csv('DisponibiliteAlimentaire_2017.csv')
population.head(5)
| Code Domaine | Domaine | Code zone | Zone | Code Élément | Élément | Code Produit | Produit | Code année | Année | Unité | Valeur | Symbole | Description du Symbole | Note | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | OA | Séries temporelles annuelles | 2 | Afghanistan | 511 | Population totale | 3010 | Population-Estimations | 2000 | 2000 | 1000 personnes | 20779.953 | X | Sources internationales sûres | NaN |
| 1 | OA | Séries temporelles annuelles | 2 | Afghanistan | 511 | Population totale | 3010 | Population-Estimations | 2001 | 2001 | 1000 personnes | 21606.988 | X | Sources internationales sûres | NaN |
| 2 | OA | Séries temporelles annuelles | 2 | Afghanistan | 511 | Population totale | 3010 | Population-Estimations | 2002 | 2002 | 1000 personnes | 22600.770 | X | Sources internationales sûres | NaN |
| 3 | OA | Séries temporelles annuelles | 2 | Afghanistan | 511 | Population totale | 3010 | Population-Estimations | 2003 | 2003 | 1000 personnes | 23680.871 | X | Sources internationales sûres | NaN |
| 4 | OA | Séries temporelles annuelles | 2 | Afghanistan | 511 | Population totale | 3010 | Population-Estimations | 2004 | 2004 | 1000 personnes | 24726.684 | X | Sources internationales sûres | NaN |
modalité population
print('Élément : ', list(population['Élément'].unique()))
Élément : ['Population totale']
print('Année : ', list(population['Année'].unique()))
Année : [2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018]
Colonnes clés : Code zone, Zone (pays), Année, Valeur (pop en milliers de personnes -> convertir en million)
print(population.columns)
Index(['Code Domaine', 'Domaine', 'Code zone', 'Zone', 'Code Élément',
'Élément', 'Code Produit', 'Produit', 'Code année', 'Année', 'Unité',
'Valeur', 'Symbole', 'Description du Symbole', 'Note'],
dtype='object')
colonnes_a_supprimer = ['Code Domaine','Domaine','Code Élément', 'Élément', 'Code Produit', 'Produit', 'Code année','Unité','Symbole', 'Description du Symbole', 'Note']
df_population = population.drop(columns = colonnes_a_supprimer, errors="ignore")
df_population = df_population.rename (columns={
"Zone" : "Pays",
"Valeur" : "Population"})
df_population['Population']=df_population['Population']*1000
df_population.head(5)
| Code zone | Pays | Année | Population | |
|---|---|---|---|---|
| 0 | 2 | Afghanistan | 2000 | 20779953.0 |
| 1 | 2 | Afghanistan | 2001 | 21606988.0 |
| 2 | 2 | Afghanistan | 2002 | 22600770.0 |
| 3 | 2 | Afghanistan | 2003 | 23680871.0 |
| 4 | 2 | Afghanistan | 2004 | 24726684.0 |
disponibiliteAlimentaire.head(5)
| Code Domaine | Domaine | Code zone | Zone | Code Élément | Élément | Code Produit | Produit | Code année | Année | Unité | Valeur | Symbole | Description du Symbole | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | FBS | Nouveaux Bilans Alimentaire | 2 | Afghanistan | 5511 | Production | 2511 | Blé et produits | 2017 | 2017 | Milliers de tonnes | 4281.0 | S | Données standardisées |
| 1 | FBS | Nouveaux Bilans Alimentaire | 2 | Afghanistan | 5611 | Importations - Quantité | 2511 | Blé et produits | 2017 | 2017 | Milliers de tonnes | 2302.0 | S | Données standardisées |
| 2 | FBS | Nouveaux Bilans Alimentaire | 2 | Afghanistan | 5072 | Variation de stock | 2511 | Blé et produits | 2017 | 2017 | Milliers de tonnes | -119.0 | S | Données standardisées |
| 3 | FBS | Nouveaux Bilans Alimentaire | 2 | Afghanistan | 5911 | Exportations - Quantité | 2511 | Blé et produits | 2017 | 2017 | Milliers de tonnes | 0.0 | S | Données standardisées |
| 4 | FBS | Nouveaux Bilans Alimentaire | 2 | Afghanistan | 5301 | Disponibilité intérieure | 2511 | Blé et produits | 2017 | 2017 | Milliers de tonnes | 6701.0 | S | Données standardisées |
modalité disponibiliteAlimentaire
print('Élément : ', list(disponibiliteAlimentaire['Élément'].unique()))
Élément : ['Production', 'Importations - Quantité', 'Variation de stock', 'Exportations - Quantité', 'Disponibilité intérieure', 'Aliments pour animaux', 'Semences', 'Pertes', 'Résidus', 'Nourriture', 'Disponibilité alimentaire en quantité (kg/personne/an)', 'Disponibilité alimentaire (Kcal/personne/jour)', 'Disponibilité de protéines en quantité (g/personne/jour)', 'Disponibilité de matière grasse en quantité (g/personne/jour)', 'Traitement', 'Autres utilisations (non alimentaire)', 'Alimentation pour touristes']
-> 'Production', Importations - Quantité, 'Exportations - Quantité', Disponibilité alimentaire en quantité (kg/personne/an).
à voir : Aliments pour animaux
print('Produit : ', list(disponibiliteAlimentaire['Produit'].unique()))
Produit : ['Blé et produits', 'Riz et produits', 'Orge et produits', 'Maïs et produits', 'Seigle et produits', 'Avoine', 'Millet et produits', 'Sorgho et produits', 'Céréales, Autres', 'Pommes de Terre et produits', 'Ignames', 'Racines nda', 'Sucre, canne', 'Sucre, betterave', 'Sucre Eq Brut', 'Edulcorants Autres', 'Miel', 'Haricots', 'Pois', 'Légumineuses Autres et produits', 'Noix et produits', 'Soja', 'Arachides Decortiquees', 'Graines de tournesol', 'Graines Colza/Moutarde', 'Graines de coton', 'Coco (Incl Coprah)', 'Sésame', 'Olives', 'Plantes Oleiferes, Autre', 'Huile de Soja', "Huile d'Arachide", 'Huile de Tournesol', 'Huile de Colza&Moutarde', 'Huile Graines de Coton', 'Huile de Palmistes', 'Huile de Palme', 'Huile de Coco', 'Huile de Sésame', "Huile d'Olive", 'Huile de Son de Riz', 'Huile de Germe de Maïs', 'Huil Plantes Oleif Autr', 'Tomates et produits', 'Oignons', 'Légumes, Autres', 'Oranges, Mandarines', 'Citrons & Limes et produits', 'Pamplemousse et produits', 'Agrumes, Autres', 'Bananes', 'Pommes et produits', 'Ananas et produits', 'Dattes', 'Raisin', 'Fruits, Autres', 'Café et produits', 'Feve de Cacao et produits', 'Thé', 'Poivre', 'Piments', 'Girofles', 'Épices, Autres', 'Vin', 'Bière', 'Boissons Fermentés', 'Boissons Alcooliques', 'Alcool, non Comestible', 'Viande de Bovins', "Viande d'Ovins/Caprins", 'Viande de Suides', 'Viande de Volailles', 'Viande, Autre', 'Abats Comestible', 'Beurre, Ghee', 'Crème', 'Graisses Animales Crue', 'Oeufs', 'Lait - Excl Beurre', 'Poissons Eau Douce', 'Aliments pour enfants', 'Miscellanees', 'Manioc et produits', 'Patates douces', 'Palmistes', 'Bananes plantains', 'Huiles de Poissons', 'Huiles de Foie de Poisso', 'Perciform', 'Poissons Pelagiques', 'Poissons Marins, Autres', 'Crustacés', 'Cephalopodes', 'Mollusques, Autres', 'Animaux Aquatiques Autre', 'Plantes Aquatiques', 'Sucre non centrifugé', 'Viande de Anim Aquatiq']
-> Oeufs, Viande de Volailles,
pour viande : 'Viande de Bovins', "Viande d'Ovins/Caprins", 'Viande de Suides', 'Viande de Volailles', 'Viande, Autre', 'Abats Comestible'.
A voir : Maïs et produits (base des rations animales), Soja (proteine vegetale essentielle pour alimentation animale), Blé et produits (utilisé en complément). Pour Afrique , il y a le Sorgho qui est très répandu et peut remplacer le maÏs si trop cher mais à voir... (se reférer à "aliments pour animaux")
print('Année : ', list(disponibiliteAlimentaire['Année'].unique()))
Année : [2017]
print('Unité : ', list(disponibiliteAlimentaire['Unité'].unique()))
Unité : ['Milliers de tonnes', 'kg', 'Kcal/personne/jour', 'g/personne/jour']
Colonnes clés : Code zone, Zone (pays), Élément, Produit, Année (2017), Valeur + Unité,
print(disponibiliteAlimentaire.columns)
Index(['Code Domaine', 'Domaine', 'Code zone', 'Zone', 'Code Élément',
'Élément', 'Code Produit', 'Produit', 'Code année', 'Année', 'Unité',
'Valeur', 'Symbole', 'Description du Symbole'],
dtype='object')
colonnes_a_supprimer = ['Code Domaine','Domaine','Code Élément', 'Code Produit', 'Code année','Symbole', 'Description du Symbole']
df_disponibiliteAlimentaire = disponibiliteAlimentaire.drop(columns = colonnes_a_supprimer, errors="ignore")
df_disponibiliteAlimentaire = df_disponibiliteAlimentaire.rename (columns={
"Zone" : "Pays",
"Valeur" : "Disponibilité alimentaire"})
df_disponibiliteAlimentaire.head(5)
| Code zone | Pays | Élément | Produit | Année | Unité | Disponibilité alimentaire | |
|---|---|---|---|---|---|---|---|
| 0 | 2 | Afghanistan | Production | Blé et produits | 2017 | Milliers de tonnes | 4281.0 |
| 1 | 2 | Afghanistan | Importations - Quantité | Blé et produits | 2017 | Milliers de tonnes | 2302.0 |
| 2 | 2 | Afghanistan | Variation de stock | Blé et produits | 2017 | Milliers de tonnes | -119.0 |
| 3 | 2 | Afghanistan | Exportations - Quantité | Blé et produits | 2017 | Milliers de tonnes | 0.0 |
| 4 | 2 | Afghanistan | Disponibilité intérieure | Blé et produits | 2017 | Milliers de tonnes | 6701.0 |
Je vais ajouter la stabilité politique (critère Politique)
stabilitePolitique = pd.read_csv('FAOSTAT_stabilitePolitique_2017.csv')
stabilitePolitique.head(5)
| Code Domaine | Domaine | Code zone (FAO) | Zone | Code Élément | Élément | Code Produit | Produit | Code année | Année | Valeur | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | FS | Données de la sécurité alimentaire | 2 | Afghanistan | 6125 | Valeur | 21032 | Stabilité politique et absence de violence/ter... | 2017 | 2017 | -2.79 |
| 1 | FS | Données de la sécurité alimentaire | 202 | Afrique du Sud | 6125 | Valeur | 21032 | Stabilité politique et absence de violence/ter... | 2017 | 2017 | -0.28 |
| 2 | FS | Données de la sécurité alimentaire | 3 | Albanie | 6125 | Valeur | 21032 | Stabilité politique et absence de violence/ter... | 2017 | 2017 | 0.37 |
| 3 | FS | Données de la sécurité alimentaire | 4 | Algérie | 6125 | Valeur | 21032 | Stabilité politique et absence de violence/ter... | 2017 | 2017 | -0.92 |
| 4 | FS | Données de la sécurité alimentaire | 79 | Allemagne | 6125 | Valeur | 21032 | Stabilité politique et absence de violence/ter... | 2017 | 2017 | 0.57 |
Colonnes clés : Code zone (FAO), Zone, Année (2017), Valeur (indice)
print(stabilitePolitique.columns)
Index(['Code Domaine', 'Domaine', 'Code zone (FAO)', 'Zone', 'Code Élément',
'Élément', 'Code Produit', 'Produit', 'Code année', 'Année', 'Valeur'],
dtype='object')
colonnes_a_supprimer = ['Code Domaine','Domaine','Code Élément','Élément','Code Produit','Produit','Code année']
df_stabilitePolitique = stabilitePolitique.drop(columns = colonnes_a_supprimer, errors="ignore")
df_stabilitePolitique = df_stabilitePolitique.rename (columns={
"Code zone (FAO)" : "Code zone",
"Zone" : "Pays",
"Valeur" : "Stabilité politique"})
df_stabilitePolitique.head(5)
| Code zone | Pays | Année | Stabilité politique | |
|---|---|---|---|---|
| 0 | 2 | Afghanistan | 2017 | -2.79 |
| 1 | 202 | Afrique du Sud | 2017 | -0.28 |
| 2 | 3 | Albanie | 2017 | 0.37 |
| 3 | 4 | Algérie | 2017 | -0.92 |
| 4 | 79 | Allemagne | 2017 | 0.57 |
Je vais ajouter : Le taux de croissance annuelle du Produit Interieur Brut (critère Economique)
croissancePIB = pd.read_csv('FAOSTAT_CroissancePIB_2017.csv')
croissancePIB.head(5)
| Code Domaine | Domaine | Code zone (FAO) | Zone | Code Élément | Élément | Code Produit | Produit | Code année | Année | Unité | Valeur | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | MK | Indicateurs macro | 2 | Afghanistan | 6129 | Croissance annuelle US$ | 22008 | Produit Intérieur Brut | 2017 | 2017 | % | 4.444345 |
| 1 | MK | Indicateurs macro | 202 | Afrique du Sud | 6129 | Croissance annuelle US$ | 22008 | Produit Intérieur Brut | 2017 | 2017 | % | 17.791964 |
| 2 | MK | Indicateurs macro | 3 | Albanie | 6129 | Croissance annuelle US$ | 22008 | Produit Intérieur Brut | 2017 | 2017 | % | 9.767331 |
| 3 | MK | Indicateurs macro | 4 | Algérie | 6129 | Croissance annuelle US$ | 22008 | Produit Intérieur Brut | 2017 | 2017 | % | 6.287893 |
| 4 | MK | Indicateurs macro | 79 | Allemagne | 6129 | Croissance annuelle US$ | 22008 | Produit Intérieur Brut | 2017 | 2017 | % | 6.368624 |
Colonnes clés : Code zone (FAO), Zone, Année (2017), Valeur
print(croissancePIB.columns)
Index(['Code Domaine', 'Domaine', 'Code zone (FAO)', 'Zone', 'Code Élément',
'Élément', 'Code Produit', 'Produit', 'Code année', 'Année', 'Unité',
'Valeur'],
dtype='object')
colonnes_a_supprimer = ['Code Domaine','Domaine','Code Élément','Élément','Code Produit','Produit','Code année','Unité']
df_croissancePIB = croissancePIB.drop(columns = colonnes_a_supprimer, errors="ignore")
df_croissancePIB = df_croissancePIB.rename (columns={
"Code zone (FAO)" : "Code zone",
"Zone" : "Pays",
"Valeur" : "taux de croissance du PIB (%)"})
df_croissancePIB.head(5)
| Code zone | Pays | Année | taux de croissance du PIB (%) | |
|---|---|---|---|---|
| 0 | 2 | Afghanistan | 2017 | 4.444345 |
| 1 | 202 | Afrique du Sud | 2017 | 17.791964 |
| 2 | 3 | Albanie | 2017 | 9.767331 |
| 3 | 4 | Algérie | 2017 | 6.287893 |
| 4 | 79 | Allemagne | 2017 | 6.368624 |
Je vais ajouter : Le Revenu National Brut par habitant (critère Economique)
rnb_par_hab = pd.read_csv('FAOSTAT_rnb_par_hab_2017.csv')
rnb_par_hab.head(5)
| Code Domaine | Domaine | Code zone (FAO) | Zone | Code Élément | Élément | Code Produit | Produit | Code année | Année | Unité | Valeur | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | MK | Indicateurs macro | 2 | Afghanistan | 6119 | Valeur US$ par habitant | 22011 | Revenu national brut | 2017 | 2017 | USD | 539.263388 |
| 1 | MK | Indicateurs macro | 202 | Afrique du Sud | 6119 | Valeur US$ par habitant | 22011 | Revenu national brut | 2017 | 2017 | USD | 6429.574062 |
| 2 | MK | Indicateurs macro | 3 | Albanie | 6119 | Valeur US$ par habitant | 22011 | Revenu national brut | 2017 | 2017 | USD | 4503.239709 |
| 3 | MK | Indicateurs macro | 4 | Algérie | 6119 | Valeur US$ par habitant | 22011 | Revenu national brut | 2017 | 2017 | USD | 4027.655361 |
| 4 | MK | Indicateurs macro | 79 | Allemagne | 6119 | Valeur US$ par habitant | 22011 | Revenu national brut | 2017 | 2017 | USD | 45470.601480 |
Colonnes clés : Code zone (FAO), Zone, Annéé (2017), Valeur
print(rnb_par_hab.columns)
Index(['Code Domaine', 'Domaine', 'Code zone (FAO)', 'Zone', 'Code Élément',
'Élément', 'Code Produit', 'Produit', 'Code année', 'Année', 'Unité',
'Valeur'],
dtype='object')
colonnes_a_supprimer = ['Code Domaine','Domaine','Code Élément','Élément','Code Produit','Produit','Code année','Unité']
df_rnb_par_hab = rnb_par_hab.drop(columns = colonnes_a_supprimer, errors="ignore")
df_rnb_par_hab = df_rnb_par_hab.rename (columns={
"Code zone (FAO)" : "Code zone",
"Zone" : "Pays",
"Valeur" : "RNB/hab (USD)"})
df_rnb_par_hab.head(5)
| Code zone | Pays | Année | RNB/hab (USD) | |
|---|---|---|---|---|
| 0 | 2 | Afghanistan | 2017 | 539.263388 |
| 1 | 202 | Afrique du Sud | 2017 | 6429.574062 |
| 2 | 3 | Albanie | 2017 | 4503.239709 |
| 3 | 4 | Algérie | 2017 | 4027.655361 |
| 4 | 79 | Allemagne | 2017 | 45470.601480 |
Je vais ajouter la surface agricole (critère Environnemental)
surfaceAgricole = pd.read_csv('FAOSTAT_superficieAgricole_2017.csv')
surfaceAgricole.head(5)
| Code Domaine | Domaine | Code zone (FAO) | Zone | Code Élément | Élément | Code Produit | Produit | Code année | Année | Unité | Valeur | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | RL | Utilisation des terres | 2 | Afghanistan | 5110 | Superficie | 6610 | Terres agricoles | 2017 | 2017 | 1000 ha | 37910.0000 |
| 1 | RL | Utilisation des terres | 202 | Afrique du Sud | 5110 | Superficie | 6610 | Terres agricoles | 2017 | 2017 | 1000 ha | 96341.0000 |
| 2 | RL | Utilisation des terres | 3 | Albanie | 5110 | Superficie | 6610 | Terres agricoles | 2017 | 2017 | 1000 ha | 1174.2810 |
| 3 | RL | Utilisation des terres | 4 | Algérie | 5110 | Superficie | 6610 | Terres agricoles | 2017 | 2017 | 1000 ha | 41335.1408 |
| 4 | RL | Utilisation des terres | 79 | Allemagne | 5110 | Superficie | 6610 | Terres agricoles | 2017 | 2017 | 1000 ha | 16687.0000 |
Colonnes clés : Code zone (FAO), Zone, Année (2017), Valeur
print(surfaceAgricole.columns)
Index(['Code Domaine', 'Domaine', 'Code zone (FAO)', 'Zone', 'Code Élément',
'Élément', 'Code Produit', 'Produit', 'Code année', 'Année', 'Unité',
'Valeur'],
dtype='object')
colonnes_a_supprimer = ['Code Domaine', 'Domaine','Code Élément','Élément','Code Produit','Produit','Code année','Unité']
df_surfaceAgricole = surfaceAgricole.drop(columns = colonnes_a_supprimer, errors="ignore")
df_surfaceAgricole = df_surfaceAgricole.rename (columns={
"Code zone (FAO)" : "Code zone",
"Zone" : "Pays",
"Valeur" : "Surface agricole (1000 ha)"})
df_surfaceAgricole.head(5)
| Code zone | Pays | Année | Surface agricole (1000 ha) | |
|---|---|---|---|---|
| 0 | 2 | Afghanistan | 2017 | 37910.0000 |
| 1 | 202 | Afrique du Sud | 2017 | 96341.0000 |
| 2 | 3 | Albanie | 2017 | 1174.2810 |
| 3 | 4 | Algérie | 2017 | 41335.1408 |
| 4 | 79 | Allemagne | 2017 | 16687.0000 |
Récapitulatif des (9+1) indicateurs choisis selon critère PESTEL, pour l'année 2017 sauf indication contraire :
POLITIQUE : Stabilité politique
ECONOMIQUE : Taux de croissance annuel du PIB, RNB/hab, TDI (à calculer).
SOCIOCULTUREL : Disponibilité alimentaire de volaille, part de volaille dans la consommation de viande (à calculer), CAGR (2000-2018, à calculer)
TECHNOLOGIQUE : Aliment pour animaux
ENVIRONNEMENTAL : Surface agricole par habitant (à calculer)
LEGAL : cf Site si pays membre (Codex Alimentarius, 188 pays)
Jusqu'ici on a : 6 tables -> df_population, df_disponibiliteAlimentaire, df_stabilitePolitique, df_croissancePIB, df_rnb_par_hab, df_surfaceAgricole
2) Nettoyage des données : mettre les données au propre et utilisable¶
CALCUL : Taux de croissance démographique annuel composé (CAGR), 2000-2018
df_population.head(5)
| Code zone | Pays | Année | Population | |
|---|---|---|---|---|
| 0 | 2 | Afghanistan | 2000 | 20779953.0 |
| 1 | 2 | Afghanistan | 2001 | 21606988.0 |
| 2 | 2 | Afghanistan | 2002 | 22600770.0 |
| 3 | 2 | Afghanistan | 2003 | 23680871.0 |
| 4 | 2 | Afghanistan | 2004 | 24726684.0 |
# extraction des populations en 2000 et 2018
pop_2000= df_population[df_population["Année"]==2000][["Code zone","Pays","Population"]].rename(columns={"Population": "Pop_2000"})
pop_2018= df_population[df_population["Année"]==2018][["Code zone","Pays","Population"]].rename(columns={"Population": "Pop_2018"})
#jointure sur les pays
df_croissancePopulation = pd.merge(pop_2000, pop_2018, on=["Code zone"])
df_croissancePopulation = df_croissancePopulation.drop(columns=["Pays_y"])
df_croissancePopulation = df_croissancePopulation.rename(columns={"Pays_x":"Pays"})
#calcul croissance totale (%)
df_croissancePopulation["Croissance_totale (%), 2000-2018"]=((df_croissancePopulation["Pop_2018"]-df_croissancePopulation["Pop_2000"])/df_croissancePopulation["Pop_2000"])*100
#calcul CAGR (%)
nb_années= 2018-2000
df_croissancePopulation["CAGR (%/an), 2000-2018"]=(((df_croissancePopulation["Pop_2018"]/df_croissancePopulation["Pop_2000"]) ** (1/nb_années))-1)*100
#resultat
df_croissancePopulation.head(5)
| Code zone | Pays | Pop_2000 | Pop_2018 | Croissance_totale (%), 2000-2018 | CAGR (%/an), 2000-2018 | |
|---|---|---|---|---|---|---|
| 0 | 2 | Afghanistan | 20779953.0 | 37171921.0 | 78.883566 | 3.283677 |
| 1 | 202 | Afrique du Sud | 44967708.0 | 57792518.0 | 28.520044 | 1.403732 |
| 2 | 3 | Albanie | 3129243.0 | 2882740.0 | -7.877400 | -0.454795 |
| 3 | 4 | Algérie | 31042235.0 | 42228408.0 | 36.035334 | 1.724390 |
| 4 | 79 | Allemagne | 81400882.0 | 83124418.0 | 2.117343 | 0.116470 |
df_check = pd.merge(pop_2000,pop_2018, on="Code zone", how="inner")
#chercher diff de noms
diff = df_check[df_check["Pays_x"] != df_check["Pays_y"]][["Code zone","Pays_x","Pays_y"]]
print(diff.head())
Empty DataFrame Columns: [Code zone, Pays_x, Pays_y] Index: []
CALCUL : Taux de dependances aux importations (TDI), pour les produits avicoles (Viande de Volailles et Oeufs), 2017
df_disponibiliteAlimentaire.head(5)
| Code zone | Pays | Élément | Produit | Année | Unité | Disponibilité alimentaire | |
|---|---|---|---|---|---|---|---|
| 0 | 2 | Afghanistan | Production | Blé et produits | 2017 | Milliers de tonnes | 4281.0 |
| 1 | 2 | Afghanistan | Importations - Quantité | Blé et produits | 2017 | Milliers de tonnes | 2302.0 |
| 2 | 2 | Afghanistan | Variation de stock | Blé et produits | 2017 | Milliers de tonnes | -119.0 |
| 3 | 2 | Afghanistan | Exportations - Quantité | Blé et produits | 2017 | Milliers de tonnes | 0.0 |
| 4 | 2 | Afghanistan | Disponibilité intérieure | Blé et produits | 2017 | Milliers de tonnes | 6701.0 |
df_disponibiliteAlimentaire.isna().sum()
Code zone 0 Pays 0 Élément 0 Produit 0 Année 0 Unité 0 Disponibilité alimentaire 0 dtype: int64
#filtre les PRODUIT avicoles + je garde les ELEMENT utiles à ma formule tdi
produits_avicoles=["Viande de Volailles", "Oeufs"]
elmt_tdi=["Production", "Importations - Quantité", "Exportations - Quantité"]
df_tdi= df_disponibiliteAlimentaire[df_disponibiliteAlimentaire["Produit"].isin(produits_avicoles)& df_disponibiliteAlimentaire["Élément"].isin(elmt_tdi)]
#pivot pour que chaque element soit une colonne à part entière (lisibilité de lecture, info direct pour chaque pays)
df_tdi= df_tdi.pivot_table(
index = ["Code zone","Pays"],
columns = "Élément",
values = "Disponibilité alimentaire",
aggfunc="sum" #sum volaille et oeufs
).reset_index()
#calcul du denominateur = production + importation - exportation
df_tdi["denominateur"]=(
df_tdi["Production"].fillna(0) + df_tdi["Importations - Quantité"].fillna(0) - df_tdi["Exportations - Quantité"].fillna(0)
)
#calcul du TDI (selon définition de FAO)
df_tdi["TDI_avicole (%)"]= np.where(
df_tdi["denominateur"]>0,
(df_tdi["Importations - Quantité"].fillna(0) / df_tdi["denominateur"])*100,
np.nan
).round(2)
#suppression colonne denominateur
df_tdi= df_tdi.drop(columns=["denominateur"])
#resultat
df_tdi.head(5)
| Élément | Code zone | Pays | Exportations - Quantité | Importations - Quantité | Production | TDI_avicole (%) |
|---|---|---|---|---|---|---|
| 0 | 1 | Arménie | 0.0 | 36.0 | 48.0 | 42.86 |
| 1 | 2 | Afghanistan | 0.0 | 83.0 | 48.0 | 63.36 |
| 2 | 3 | Albanie | 1.0 | 38.0 | 64.0 | 37.62 |
| 3 | 4 | Algérie | 0.0 | 2.0 | 665.0 | 0.30 |
| 4 | 7 | Angola | 0.0 | 300.0 | 47.0 | 86.46 |
df_tdi.columns.name = None
df_tdi.head(5)
| Code zone | Pays | Exportations - Quantité | Importations - Quantité | Production | TDI_avicole (%) | |
|---|---|---|---|---|---|---|
| 0 | 1 | Arménie | 0.0 | 36.0 | 48.0 | 42.86 |
| 1 | 2 | Afghanistan | 0.0 | 83.0 | 48.0 | 63.36 |
| 2 | 3 | Albanie | 1.0 | 38.0 | 64.0 | 37.62 |
| 3 | 4 | Algérie | 0.0 | 2.0 | 665.0 | 0.30 |
| 4 | 7 | Angola | 0.0 | 300.0 | 47.0 | 86.46 |
df_tdi.isna().sum()
Code zone 0 Pays 0 Exportations - Quantité 26 Importations - Quantité 0 Production 2 TDI_avicole (%) 0 dtype: int64
missing_rows = df_tdi[df_tdi.isna().any(axis=1)]
print(missing_rows)
Code zone Pays Exportations - Quantité \
9 12 Bahamas NaN
11 16 Bangladesh NaN
21 35 Cabo Verde NaN
22 37 République centrafricaine NaN
30 49 Cuba NaN
46 72 Djibouti NaN
49 75 Gambie NaN
53 83 Kiribati NaN
55 86 Grenade NaN
57 90 Guinée NaN
59 93 Haïti NaN
92 132 Maldives NaN
95 136 Mauritanie NaN
98 141 Mongolie NaN
100 144 Mozambique NaN
103 149 Népal NaN
105 153 Nouvelle-Calédonie NaN
107 155 Vanuatu NaN
121 175 Guinée-Bissau NaN
122 176 Timor-Leste NaN
129 191 Saint-Vincent-et-les Grenadines NaN
130 193 Sao Tomé-et-Principe NaN
143 213 Turkménistan NaN
157 233 Burkina Faso NaN
161 238 Éthiopie NaN
169 276 Soudan NaN
Importations - Quantité Production TDI_avicole (%)
9 26.0 7.0 78.79
11 0.0 942.0 0.00
21 13.0 4.0 76.47
22 5.0 10.0 33.33
30 313.0 141.0 68.94
46 4.0 NaN 100.00
49 20.0 3.0 86.96
53 1.0 1.0 50.00
55 7.0 2.0 77.78
57 37.0 39.0 48.68
59 91.0 14.0 86.67
92 21.0 NaN 100.00
95 29.0 11.0 72.50
98 18.0 5.0 78.26
100 36.0 145.0 19.89
103 0.0 126.0 0.00
105 9.0 3.0 75.00
107 4.0 2.0 66.67
121 6.0 4.0 60.00
122 11.0 2.0 84.62
129 9.0 1.0 90.00
130 2.0 1.0 66.67
143 9.0 71.0 11.25
157 0.0 104.0 0.00
161 1.0 69.0 1.43
169 3.0 123.0 2.38
pourcentage_nan = df_tdi.isna().sum()/len(df_tdi) *100
print(pourcentage_nan)
Code zone 0.000000 Pays 0.000000 Exportations - Quantité 15.294118 Importations - Quantité 0.000000 Production 1.176471 TDI_avicole (%) 0.000000 dtype: float64
Memo :
Les NAN sont remplacés par 0 lors du calucul du tdi
26 pays avec données totalement manquantes sur les 2 produits (très rares, et pour exportation),
de plus les pays concernés par ces manques sont globalement des petits marchés ou peu stratégiques donc impact limité sur l'analyse.
CALCUL : Part avicole (volailles + oeufs) dans la consommation de viande et oeufs (%), 2017
#filtre sur les produits
produits_avicoles=["Viande de Volailles", "Oeufs"]
produits_viandes_oeufs= ["Viande de Bovins", "Viande d'Ovins/Caprins", "Viande de Suides", "Viande de Volailles", "Viande, Autre", "Oeufs"] #je ne compte pas les abats comestibles car ça peut provenir de toutes viandes confondues ( mouton, poulet etc.).
elmt= ["Disponibilité alimentaire en quantité (kg/personne/an)"]
part_avicole= df_disponibiliteAlimentaire[df_disponibiliteAlimentaire["Produit"].isin(produits_viandes_oeufs)& df_disponibiliteAlimentaire["Élément"].isin(elmt)]
#pivot pour que les produits soient en colonnes pour chaque pays
part_avicole=part_avicole.pivot_table(
index = ["Code zone","Pays"],
columns = "Produit",
values = "Disponibilité alimentaire",
).reset_index()
#calcul du numerateur et denominateur
num = part_avicole["Oeufs"] + part_avicole["Viande de Volailles"]
den = part_avicole[produits_viandes_oeufs].sum(axis=1) #je fais la somme horizontale des valeurs de tous les produits , par ligne : total par pays
df_part_avicole= pd.DataFrame({
"Code zone": part_avicole["Code zone"],
"Pays": part_avicole["Pays"],
"Quantité de produits avicoles (kg/hab/an) ": part_avicole[produits_avicoles].sum(axis=1),
"Part avicole (%)": np.where(den>0, (num/den) * 100, np.nan).round(2)
} ).sort_values("Part avicole (%)",ascending=False)
#part_avicole.head(5)
df_part_avicole.head(5)
| Code zone | Pays | Quantité de produits avicoles (kg/hab/an) | Part avicole (%) | |
|---|---|---|---|---|
| 23 | 38 | Sri Lanka | 12.05 | 90.60 |
| 74 | 109 | Jamaïque | 53.08 | 87.10 |
| 68 | 103 | Iraq | 24.39 | 85.58 |
| 58 | 91 | Guyana | 40.20 | 85.39 |
| 132 | 194 | Arabie saoudite | 49.92 | 82.27 |
pourcentage_nan = df_part_avicole.isna().sum()/len(df_part_avicole) *100
print(pourcentage_nan)
Code zone 0.0 Pays 0.0 Quantité de produits avicoles (kg/hab/an) 0.0 Part avicole (%) 0.0 dtype: float64
CALCUL : Surface agricole / hab
df_surfaceAgricole.head(5)
| Code zone | Pays | Année | Surface agricole (1000 ha) | |
|---|---|---|---|---|
| 0 | 2 | Afghanistan | 2017 | 37910.0000 |
| 1 | 202 | Afrique du Sud | 2017 | 96341.0000 |
| 2 | 3 | Albanie | 2017 | 1174.2810 |
| 3 | 4 | Algérie | 2017 | 41335.1408 |
| 4 | 79 | Allemagne | 2017 | 16687.0000 |
#je filtre pop sur 2017 et refais une table pour surface sans annee
pop_2017= df_population[df_population["Année"]==2017][["Code zone","Pays","Population"]].rename(columns={"Population": "Pop_2017"})
sur_2017 = df_surfaceAgricole.drop(columns=["Année"])
#Attention surface Agricole est en 1000 ha -> convertir en ha
sur_2017["Surface agricole (ha) "]= sur_2017["Surface agricole (1000 ha)"]*1000
#jointure (left join car je garde sur_2017 et je la modifie)
df_surfaceAgricole_complet = pd.merge(sur_2017, pop_2017, on="Code zone", how="left", suffixes=("_surfaceAgricole","_population"))
#calcul surface agricole / hab
df_surfaceAgricole_complet["Surface agricole par hab (ha/hab)"]=(df_surfaceAgricole_complet["Surface agricole (ha) "] / df_surfaceAgricole_complet["Pop_2017"]).round(4)
df_surfaceAgricole_complet = df_surfaceAgricole_complet.drop(columns=["Surface agricole (1000 ha)"])
df_surfaceAgricole_complet.head(5)
| Code zone | Pays_surfaceAgricole | Surface agricole (ha) | Pays_population | Pop_2017 | Surface agricole par hab (ha/hab) | |
|---|---|---|---|---|---|---|
| 0 | 2 | Afghanistan | 37910000.0 | Afghanistan | 36296113.0 | 1.0445 |
| 1 | 202 | Afrique du Sud | 96341000.0 | Afrique du Sud | 57009756.0 | 1.6899 |
| 2 | 3 | Albanie | 1174281.0 | Albanie | 2884169.0 | 0.4071 |
| 3 | 4 | Algérie | 41335140.8 | Algérie | 41389189.0 | 0.9987 |
| 4 | 79 | Allemagne | 16687000.0 | Allemagne | 82658409.0 | 0.2019 |
df_surfaceAgricole_complet.isna().sum()
Code zone 0 Pays_surfaceAgricole 0 Surface agricole (ha) 0 Pays_population 2 Pop_2017 2 Surface agricole par hab (ha/hab) 2 dtype: int64
pourcentage_nan = df_surfaceAgricole_complet.isna().sum()/len(df_surfaceAgricole_complet) *100
print(pourcentage_nan)
Code zone 0.000000 Pays_surfaceAgricole 0.000000 Surface agricole (ha) 0.000000 Pays_population 0.881057 Pop_2017 0.881057 Surface agricole par hab (ha/hab) 0.881057 dtype: float64
il y a 2 pays presents dans la table surface agricole mais pas dans dans la table population :
missing_rows = df_surfaceAgricole_complet[df_surfaceAgricole_complet.isna().any(axis=1)]
print(missing_rows)
Code zone Pays_surfaceAgricole Surface agricole (ha) Pays_population \
39 351 Chine 522997100.0 NaN
87 161 Île Norfolk 1000.0 NaN
Pop_2017 Surface agricole par hab (ha/hab)
39 NaN NaN
87 NaN NaN
df_surfaceAgricole_complet[df_surfaceAgricole_complet["Code zone"]==41]
| Code zone | Pays_surfaceAgricole | Surface agricole (ha) | Pays_population | Pop_2017 | Surface agricole par hab (ha/hab) | |
|---|---|---|---|---|---|---|
| 41 | 41 | Chine, continentale | 522199000.0 | Chine, continentale | 1.421022e+09 | 0.3675 |
La Chine n'est pas perdue en réalité dans surfaceAgricole_complet car elle est présente en doublons implicite via "La Chine Continentale".
Quant à Île Norfolk, il s'agit d'un petit marché donc non pertinent à retenir.
Les deux seront nettoyés automatiquement de notre table finale car données manquantes en TDI avicole notamment.
CALCUL : aliment pour animaux
#filtre aliment pour animaux
df_aliment_pour_animaux= df_disponibiliteAlimentaire.loc[df_disponibiliteAlimentaire["Élément"]=="Aliments pour animaux",["Code zone", "Pays", "Produit","Unité","Disponibilité alimentaire"]]
df_aliment_pour_animaux.head()
| Code zone | Pays | Produit | Unité | Disponibilité alimentaire | |
|---|---|---|---|---|---|
| 5 | 2 | Afghanistan | Blé et produits | Milliers de tonnes | 76.0 |
| 18 | 2 | Afghanistan | Riz et produits | Milliers de tonnes | 0.0 |
| 32 | 2 | Afghanistan | Orge et produits | Milliers de tonnes | 67.0 |
| 46 | 2 | Afghanistan | Maïs et produits | Milliers de tonnes | 111.0 |
| 59 | 2 | Afghanistan | Seigle et produits | Milliers de tonnes | 0.0 |
print('Produit : ', list(df_aliment_pour_animaux['Produit'].unique()))
Produit : ['Blé et produits', 'Riz et produits', 'Orge et produits', 'Maïs et produits', 'Seigle et produits', 'Sorgho et produits', 'Céréales, Autres', 'Sucre, canne', 'Sucre, betterave', 'Pois', 'Légumineuses Autres et produits', 'Arachides Decortiquees', 'Graines Colza/Moutarde', 'Coco (Incl Coprah)', 'Plantes Oleiferes, Autre', 'Raisin', 'Oeufs', 'Lait - Excl Beurre', 'Avoine', 'Millet et produits', 'Pommes de Terre et produits', 'Patates douces', 'Ignames', 'Racines nda', 'Edulcorants Autres', 'Haricots', 'Soja', 'Graines de tournesol', 'Graines de coton', 'Sésame', 'Huil Plantes Oleif Autr', 'Légumes, Autres', 'Viande, Autre', 'Abats Comestible', 'Huiles de Poissons', 'Perciform', 'Poissons Pelagiques', 'Poissons Marins, Autres', 'Palmistes', 'Olives', 'Beurre, Ghee', 'Manioc et produits', 'Sucre Eq Brut', 'Huile de Colza&Moutarde', 'Graisses Animales Crue', 'Crustacés', 'Huile de Sésame', 'Poissons Eau Douce', 'Tomates et produits', 'Pommes et produits', 'Girofles', 'Huile de Soja', 'Bananes plantains', 'Bananes', 'Huiles de Foie de Poisso', "Viande d'Ovins/Caprins", 'Cephalopodes', "Huile d'Arachide", 'Huile Graines de Coton', 'Huile de Palmistes', 'Huile de Palme', 'Huile de Coco', 'Sucre non centrifugé', "Huile d'Olive", 'Oranges, Mandarines', 'Dattes', 'Fruits, Autres', 'Feve de Cacao et produits', 'Viande de Bovins', 'Oignons', 'Mollusques, Autres', 'Plantes Aquatiques', 'Miel', 'Noix et produits', 'Huile de Tournesol', 'Citrons & Limes et produits', 'Pamplemousse et produits', 'Agrumes, Autres', 'Ananas et produits', 'Café et produits', 'Thé', 'Poivre', 'Piments', 'Épices, Autres', 'Vin', 'Bière', 'Boissons Fermentés', 'Boissons Alcooliques', 'Alcool, non Comestible', 'Viande de Suides', 'Viande de Volailles', 'Crème', 'Aliments pour enfants', 'Miscellanees']
ALIMENTATION des poules (base avicole, marqueurs d'industrialisation avicole) :
Céréales de base (énergie) : 'Maïs et produits', 'Sorgho et produits', 'Blé et produits'.
Protéagineux/oléagineux (proteine pour les rations) : 'Soja', 'Graines de tournesol', 'Graines Colza/Moutarde'
Ces 6 produits représentent le coeur de l'alimentation avicole INDUSTRIELLE moderne dans le monde. Les autres (riz, manioc, patates douces...) sont utilisés localement mais pas caractéristiques d'une filière avicole structurée.
#produits clés pour l'alimentation avicole industrielle :
produits_indust_avicole = ['Maïs et produits', 'Sorgho et produits', 'Blé et produits', 'Soja', 'Graines de tournesol', 'Graines Colza/Moutarde']
#filtrer uniquement les aliments pour animaux (element) et produits avicole (produits) :
df_aliment_avicole_temp = df_aliment_pour_animaux[df_aliment_pour_animaux["Produit"].isin(produits_indust_avicole)][["Code zone","Pays","Produit","Disponibilité alimentaire"]]
#calcul somme dispoAlim de ces produits pour animaux par pays :
df_aliment_avicole = (df_aliment_avicole_temp.groupby(["Code zone","Pays"], as_index=False)["Disponibilité alimentaire"].sum()
)
#unité : Milliers de tonnes
df_aliment_avicole = df_aliment_avicole.rename (columns={
"Disponibilité alimentaire" : "Aliments avicoles (Milliers de tonnes)"})
#résultat
df_aliment_avicole.head()
| Code zone | Pays | Aliments avicoles (Milliers de tonnes) | |
|---|---|---|---|
| 0 | 1 | Arménie | 138.0 |
| 1 | 2 | Afghanistan | 188.0 |
| 2 | 3 | Albanie | 398.0 |
| 3 | 4 | Algérie | 3973.0 |
| 4 | 7 | Angola | 789.0 |
pourcentage_nan = df_aliment_avicole.isna().sum()/len(df_aliment_avicole) *100
print(pourcentage_nan)
Code zone 0.0 Pays 0.0 Aliments avicoles (Milliers de tonnes) 0.0 dtype: float64
Vérification du nombre total d'habitants dans le monde , sachant qu'il devrait y avoir environ 7 milliards
population_mondiale_2017 = df_population[(df_population['Année']==2017)]
population_mondiale_2017.head(5)
| Code zone | Pays | Année | Population | |
|---|---|---|---|---|
| 17 | 2 | Afghanistan | 2017 | 36296113.0 |
| 36 | 202 | Afrique du Sud | 2017 | 57009756.0 |
| 55 | 3 | Albanie | 2017 | 2884169.0 |
| 74 | 4 | Algérie | 2017 | 41389189.0 |
| 93 | 79 | Allemagne | 2017 | 82658409.0 |
print('Nombre de population en 2017 : ', population_mondiale_2017['Population'].sum())
Nombre de population en 2017 : 7548134111.0
Verification si doublons : non
def doublons(df):
print(len(df)-len(df.drop_duplicates()), 'doublons')
doublons(df_population) #changer la table pour verifier les autres
0 doublons
Mise au point Pays : nombre, pays manquants dans certaines df...
print('Nombre de pays :', df_population['Code zone'].nunique(), 'dans df_population')
print('Nombre de pays :', df_disponibiliteAlimentaire['Code zone'].nunique(), 'dans df_disponibiliteAlimentaire')
print('Nombre de pays :', df_stabilitePolitique['Code zone'].nunique(), 'dans df_stabilitePolitique')
print('Nombre de pays :', df_croissancePIB['Code zone'].nunique(), 'dans df_croissancePIB')
print('Nombre de pays :', df_rnb_par_hab['Code zone'].nunique(), 'dans df_rnb_par_hab')
print('Nombre de pays :', df_surfaceAgricole['Code zone'].nunique(), 'dans df_surfaceAgricole')
print('table dérivé:')
print('Nombre de pays :', df_croissancePopulation['Code zone'].nunique(), 'dans df_croissancePopulation')
print('Nombre de pays :', df_part_avicole['Code zone'].nunique(), 'dans df_part_avicole')
print('Nombre de pays :', df_tdi['Code zone'].nunique(), 'dans df_tdi')
print('Nombre de pays :', df_surfaceAgricole_complet['Code zone'].nunique(), 'dans df_surfaceAgricole_complet')
print('Nombre de pays :', df_aliment_avicole['Code zone'].nunique(), 'dans df_aliment_avicole')
Nombre de pays : 238 dans df_population Nombre de pays : 174 dans df_disponibiliteAlimentaire Nombre de pays : 195 dans df_stabilitePolitique Nombre de pays : 210 dans df_croissancePIB Nombre de pays : 210 dans df_rnb_par_hab Nombre de pays : 227 dans df_surfaceAgricole table dérivé: Nombre de pays : 227 dans df_croissancePopulation Nombre de pays : 172 dans df_part_avicole Nombre de pays : 170 dans df_tdi Nombre de pays : 227 dans df_surfaceAgricole_complet Nombre de pays : 170 dans df_aliment_avicole
# Affichage Les pays dans dispAlim mais pas dans df_part_avicole
diff_countries = df_disponibiliteAlimentaire[~df_disponibiliteAlimentaire['Code zone'].isin(df_part_avicole['Code zone'])]
pays_manquants=diff_countries['Pays'].unique()
print('Les 2 pays manquants dans df_part_avicole sont :', pays_manquants)
Les 2 pays manquants dans df_part_avicole sont : ['Bermudes' 'Brunéi Darussalam']
# Affichage Les pays dans dispAlim mais pas dans df_tdi
diff_countries = df_disponibiliteAlimentaire[~df_disponibiliteAlimentaire['Code zone'].isin(df_tdi['Code zone'])]
pays_manquants=diff_countries['Pays'].unique()
print('Les 4 pays manquants dans df_tdi sont :', pays_manquants)
Les 4 pays manquants dans df_tdi sont : ['Bermudes' 'Brunéi Darussalam' 'Ouzbékistan' 'République démocratique populaire lao']
# Affichage Les pays dans dispAlim mais pas dans df_aliment_avicole
diff_countries = df_disponibiliteAlimentaire[~df_disponibiliteAlimentaire['Code zone'].isin(df_aliment_avicole['Code zone'])]
pays_manquants=diff_countries['Pays'].unique()
print('Les 4 pays manquants dans df_aliment_avicole sont :', pays_manquants)
Les 4 pays manquants dans df_aliment_avicole sont : ['Bermudes' 'Brunéi Darussalam' 'Ouzbékistan' 'République démocratique populaire lao']
La table disponibiliteAlimentaire contient le coeur des données fondamentales pour l'analyse.
Nous l'utiliserons pas directement mais nous utiliserons ses tables dérivées (df_tdi et df_part_avicole et df_aliment_avicole)
On remarque qu'il manque 2 pays dans df_part_avicole par rapport à la disponibilitéAlimentaire : Bermudes, Brunei Darussalam
et il manque 4 pays dans df_tdi : 'Bermudes','Brunéi Darussalam', 'Ouzbékistan', 'République démocratique populaire lao'
Nous pouvons donc supprimer systématiquement les pays : Bermudes, Brunei Darussalam
Puis nous choissisons de supprimer également les 2 autres pays qui n'impacte pas l'objectif initial (le choix de pays candidats prioritaires pour exportation).
Ainsi, nous allons prendre comme table de base en pivot la table df_tdi qui contient les pays ayant les données incontournables.
je vais donc vérifier la correspondance des pays entre df_tdi et les autres tables
#dans table population
diff_countries = df_tdi['Code zone'].isin(df_population['Code zone']) == False
df_tdi[diff_countries].head(5)
| Code zone | Pays | Exportations - Quantité | Importations - Quantité | Production | TDI_avicole (%) |
|---|
#dans table df_stabilitePolitique
diff_countries = df_tdi['Code zone'].isin(df_stabilitePolitique['Code zone']) == False
df_tdi[diff_countries].head(20)
| Code zone | Pays | Exportations - Quantité | Importations - Quantité | Production | TDI_avicole (%) | |
|---|---|---|---|---|---|---|
| 26 | 41 | Chine, continentale | 692.0 | 452.0 | 54694.0 | 0.83 |
| 45 | 70 | Polynésie française | 0.0 | 15.0 | 3.0 | 83.33 |
| 105 | 153 | Nouvelle-Calédonie | NaN | 9.0 | 3.0 | 75.00 |
| 116 | 169 | Paraguay | 4.0 | 3.0 | 131.0 | 2.31 |
| 144 | 214 | Chine, Taiwan Province de | 11.0 | 163.0 | 1053.0 | 13.53 |
En fait dans stabilité politique, concernant la Chine, il n'y a que les valeurs de Macao (Code Zone 128) et Hong-Kong (Code Zone 96).
Cependant, nous avons les données (à partir du projet 8) de stabilité politique en 2017 de Taiwan (0.86) et de la Chine, continentale (-0.23).
De la même manière, nous trouvons aussi pour Paraguay en 2017 (0.0).
Pour les pays d'outre-mer français (Polynésie française, Nouvelle-Calédonie), nous retiendrons la valeur de la stabilité politique de la France, les bases ne proposant pas d'indicateur séparé. Bien que cela n'est pas fidèle à 100%
(ex : en Nouvelle-Calédonie, il y a eu plusieurs référendums sur l'independance, parfois des tensions.
ex2 : en Polynésie, la vie politique est plus stable, mais il existe des débats sur l'autonomie).
df_stabilitePolitique[df_stabilitePolitique["Pays"]=="France"]
| Code zone | Pays | Année | Stabilité politique | |
|---|---|---|---|---|
| 63 | 68 | France | 2017 | 0.27 |
# Tableau des imputations à ajouter
imputations = pd.DataFrame([
{"Code zone": 41, "Pays":"Chine, continentale","Stabilité politique":-0.23},
{"Code zone": 70, "Pays":"Polynésie française","Stabilité politique":0.27},
{"Code zone": 153, "Pays":"Nouvelle-Calédonie","Stabilité politique":0.27},
{"Code zone": 169, "Pays":"Paraguay","Stabilité politique":0.0},
{"Code zone": 214, "Pays":"Chine, Taiwan Province de","Stabilité politique":0.86}
])
#imputations des valeurs dans df_stabilitePolitique via concatenation
df_stabilitePolitique= pd.concat([df_stabilitePolitique, imputations], ignore_index=True)
df_stabilitePolitique[df_stabilitePolitique["Code zone"]==214] #changer le Code zone pour verifier les autres ajout
| Code zone | Pays | Année | Stabilité politique | |
|---|---|---|---|---|
| 199 | 214 | Chine, Taiwan Province de | NaN | 0.86 |
#dans table df_stabilitePolitique
diff_countries = df_tdi['Code zone'].isin(df_stabilitePolitique['Code zone']) == False
df_tdi[diff_countries].head(20)
| Code zone | Pays | Exportations - Quantité | Importations - Quantité | Production | TDI_avicole (%) |
|---|
#dans table df_croissancePIB
diff_countries = df_tdi['Code zone'].isin(df_croissancePIB['Code zone']) == False
df_tdi[diff_countries].head(5)
| Code zone | Pays | Exportations - Quantité | Importations - Quantité | Production | TDI_avicole (%) | |
|---|---|---|---|---|---|---|
| 144 | 214 | Chine, Taiwan Province de | 11.0 | 163.0 | 1053.0 | 13.53 |
#dans table df_rnb_par_hab
diff_countries = df_tdi['Code zone'].isin(df_rnb_par_hab['Code zone']) == False
df_tdi[diff_countries].head(5)
| Code zone | Pays | Exportations - Quantité | Importations - Quantité | Production | TDI_avicole (%) | |
|---|---|---|---|---|---|---|
| 144 | 214 | Chine, Taiwan Province de | 11.0 | 163.0 | 1053.0 | 13.53 |
Les données macroéconomique (PIB,RNB...) ne sont pas disponibles dans FAOSTAT, en raison du statut politique particulier de Taiwan.
Pour obtenir le PIB nominal de Taiwan (sans correction de l'inflation comme dans mes données de FAO), nous utiliserons les données du DGBAS de Taiwan (équivalent de l'INSEE pour eux) : https://eng.stat.gov.tw//Point.aspx?sid=t.1&n=4200&sms=11713
On prendra
GDP(at Current Prices)(million NT dollars) = PIB nominal (non corrigé de l'inflation) de 2016 et 2017 pour calculer le taux de croissance :
((GDP 2017 - GDP 2016) / GDP 2016)100 = ((18 012 387 - 17 555 268)/17 555 268 )100= 2.60388506 %
Per Capita GNI(US dollars) = RNB/hab (US dollars) de 2017 = 25 745
df_croissancePIB[df_croissancePIB["Code zone"]==214]
| Code zone | Pays | Année | taux de croissance du PIB (%) |
|---|
df_rnb_par_hab[df_rnb_par_hab["Code zone"]==214]
| Code zone | Pays | Année | RNB/hab (USD) |
|---|
# Tableau des imputations à ajouter
imputations_pib = pd.DataFrame([
{"Code zone": 214, "Pays":"Chine, Taiwan Province de","taux de croissance du PIB (%)":2.603885}
])
imputations_rnb = pd.DataFrame([
{"Code zone": 214, "Pays":"Chine, Taiwan Province de","RNB/hab (USD)":25745}
])
#imputations des valeurs via concatenation
df_croissancePIB= pd.concat([df_croissancePIB, imputations_pib], ignore_index=True)
df_rnb_par_hab= pd.concat([df_rnb_par_hab, imputations_rnb], ignore_index=True)
#dans table df_surfaceAgricole (c'est pareil pour df_surfaceAgricole_complet)
diff_countries = df_tdi['Code zone'].isin(df_surfaceAgricole['Code zone']) == False
df_tdi[diff_countries].head(5)
| Code zone | Pays | Exportations - Quantité | Importations - Quantité | Production | TDI_avicole (%) | |
|---|---|---|---|---|---|---|
| 88 | 128 | Chine - RAS de Macao | 0.0 | 36.0 | 3.0 | 92.31 |
L'agriculture à Macao n'existe quasiment pas.
Choix 1 : Nous pouvons imputer la valeur minimale trouvée dans notre table df_surfaceAgricole_complet : 0.000100 ha/hab.
Choix 2 : Nous pouvons supprimer Macao de notre table. Macao présente un tdi avicole de 92% mais cette valeur ne traduit pas une opportunité d'exportation. En pratique, Macao dépend quasi exclusivement des importations de la Chine continentale.
Nous retiendrons le second choix.
#supprimer Macao par son code Zone dans df_tdi
df_tdi= df_tdi[df_tdi["Code zone"]!= 128]
#verification
diff_countries = df_tdi['Code zone'].isin(df_surfaceAgricole['Code zone']) == False
df_tdi[diff_countries].head(5)
| Code zone | Pays | Exportations - Quantité | Importations - Quantité | Production | TDI_avicole (%) |
|---|
#dans table df_croissancePopulation
diff_countries = df_tdi['Code zone'].isin(df_croissancePopulation['Code zone']) == False
df_tdi[diff_countries].head(5)
| Code zone | Pays | Exportations - Quantité | Importations - Quantité | Production | TDI_avicole (%) | |
|---|---|---|---|---|---|---|
| 167 | 272 | Serbie | 10.0 | 15.0 | 173.0 | 8.43 |
| 168 | 273 | Monténégro | 0.0 | 10.0 | 10.0 | 50.00 |
| 169 | 276 | Soudan | NaN | 3.0 | 123.0 | 2.38 |
La Serbie, le Monténégro et le Soudan ne pourront pas être intégrés en raison de données manquantes sur la croissance démographique.
Leur profil n'étant pas stratégiquement pertinent (Faible dépendance aux importations ou marché trop petit), nous avons choisis de les exclure.
#supprimer les 3 pays par son code Zone dans df_tdi
df_tdi= df_tdi[df_tdi["Code zone"]!= 272]
df_tdi= df_tdi[df_tdi["Code zone"]!= 273]
df_tdi= df_tdi[df_tdi["Code zone"]!= 276]
#verification
diff_countries = df_tdi['Code zone'].isin(df_croissancePopulation['Code zone']) == False
df_tdi[diff_countries].head(5)
| Code zone | Pays | Exportations - Quantité | Importations - Quantité | Production | TDI_avicole (%) |
|---|
#dans table df_aliment_avicole
diff_countries = df_tdi['Code zone'].isin(df_aliment_avicole['Code zone']) == False
df_tdi[diff_countries].head(5)
| Code zone | Pays | Exportations - Quantité | Importations - Quantité | Production | TDI_avicole (%) |
|---|
#dans table df_part_avicole
diff_countries = df_tdi['Code zone'].isin(df_part_avicole['Code zone']) == False
df_tdi[diff_countries].head(5)
| Code zone | Pays | Exportations - Quantité | Importations - Quantité | Production | TDI_avicole (%) |
|---|
Suppression colonnes inutiles (préparation des tables pour jointures)
#Suppression des colonnes inutiles df_tdi
df_tdi_jointure = df_tdi[["Code zone","Pays","Importations - Quantité","TDI_avicole (%)"]]
df_tdi_jointure
| Code zone | Pays | Importations - Quantité | TDI_avicole (%) | |
|---|---|---|---|---|
| 0 | 1 | Arménie | 36.0 | 42.86 |
| 1 | 2 | Afghanistan | 83.0 | 63.36 |
| 2 | 3 | Albanie | 38.0 | 37.62 |
| 3 | 4 | Algérie | 2.0 | 0.30 |
| 4 | 7 | Angola | 300.0 | 86.46 |
| ... | ... | ... | ... | ... |
| 162 | 244 | Samoa | 17.0 | 100.00 |
| 163 | 249 | Yémen | 78.0 | 25.00 |
| 164 | 251 | Zambie | 12.0 | 10.81 |
| 165 | 255 | Belgique | 458.0 | 141.36 |
| 166 | 256 | Luxembourg | 19.0 | 95.00 |
166 rows × 4 columns
#Suppression des colonnes inutiles df_croissancePIB
df_croissancePIB_jointure = df_croissancePIB[["Code zone","taux de croissance du PIB (%)"]]
df_croissancePIB_jointure.head()
| Code zone | taux de croissance du PIB (%) | |
|---|---|---|
| 0 | 2 | 4.444345 |
| 1 | 202 | 17.791964 |
| 2 | 3 | 9.767331 |
| 3 | 4 | 6.287893 |
| 4 | 79 | 6.368624 |
#Suppression des colonnes inutiles df_rnb_par_hab
df_rnb_par_hab_jointure = df_rnb_par_hab[["Code zone","RNB/hab (USD)"]]
df_rnb_par_hab_jointure.head()
| Code zone | RNB/hab (USD) | |
|---|---|---|
| 0 | 2 | 539.263388 |
| 1 | 202 | 6429.574062 |
| 2 | 3 | 4503.239709 |
| 3 | 4 | 4027.655361 |
| 4 | 79 | 45470.601480 |
#Suppression des colonnes inutiles df_part_avicole
df_part_avicole_jointure = df_part_avicole[["Code zone","Quantité de produits avicoles (kg/hab/an) ","Part avicole (%)"]]
df_part_avicole_jointure.head()
| Code zone | Quantité de produits avicoles (kg/hab/an) | Part avicole (%) | |
|---|---|---|---|
| 23 | 38 | 12.05 | 90.60 |
| 74 | 109 | 53.08 | 87.10 |
| 68 | 103 | 24.39 | 85.58 |
| 58 | 91 | 40.20 | 85.39 |
| 132 | 194 | 49.92 | 82.27 |
#Suppression des colonnes inutiles df_croissancePopulation
df_croissancePopulation_jointure = df_croissancePopulation[["Code zone","CAGR (%/an), 2000-2018"]]
df_croissancePopulation_jointure.head()
| Code zone | CAGR (%/an), 2000-2018 | |
|---|---|---|
| 0 | 2 | 3.283677 |
| 1 | 202 | 1.403732 |
| 2 | 3 | -0.454795 |
| 3 | 4 | 1.724390 |
| 4 | 79 | 0.116470 |
#Suppression des colonnes inutiles df_aliment_avicole
df_aliment_avicole_jointure = df_aliment_avicole[["Code zone","Aliments avicoles (Milliers de tonnes)"]]
df_aliment_avicole_jointure.head()
| Code zone | Aliments avicoles (Milliers de tonnes) | |
|---|---|---|
| 0 | 1 | 138.0 |
| 1 | 2 | 188.0 |
| 2 | 3 | 398.0 |
| 3 | 4 | 3973.0 |
| 4 | 7 | 789.0 |
#Suppression des colonnes inutiles df_surfaceAgricole_complet
df_surfaceAgricole_complet_jointure = df_surfaceAgricole_complet[["Code zone","Pop_2017","Surface agricole par hab (ha/hab)"]]
df_surfaceAgricole_complet_jointure.head()
| Code zone | Pop_2017 | Surface agricole par hab (ha/hab) | |
|---|---|---|---|
| 0 | 2 | 36296113.0 | 1.0445 |
| 1 | 202 | 57009756.0 | 1.6899 |
| 2 | 3 | 2884169.0 | 0.4071 |
| 3 | 4 | 41389189.0 | 0.9987 |
| 4 | 79 | 82658409.0 | 0.2019 |
#Suppression des colonnes inutiles df_stabilitePolitique
df_stabilitePolitique_jointure = df_stabilitePolitique[["Code zone","Stabilité politique"]]
df_stabilitePolitique_jointure.head()
| Code zone | Stabilité politique | |
|---|---|---|
| 0 | 2 | -2.79 |
| 1 | 202 | -0.28 |
| 2 | 3 | 0.37 |
| 3 | 4 | -0.92 |
| 4 | 79 | 0.57 |
print("Base TDI :", df_tdi_jointure["Code zone"].nunique())
df_merge = df_tdi_jointure.merge(df_croissancePIB_jointure, on="Code zone", how="inner")
print("Après jointure avec taux de croissancePIB :", df_merge["Code zone"].nunique())
df_merge = df_merge.merge(df_rnb_par_hab_jointure, on="Code zone", how="inner")
print("Après jointure avec RNB/hab :", df_merge["Code zone"].nunique())
df_merge = df_merge.merge(df_part_avicole_jointure, on="Code zone", how="inner")
print("Après jointure avec part_avicole :", df_merge["Code zone"].nunique())
df_merge = df_merge.merge(df_croissancePopulation_jointure, on="Code zone", how="inner")
print("Après jointure avec croissancePopulation :", df_merge["Code zone"].nunique())
df_merge = df_merge.merge(df_aliment_avicole_jointure, on="Code zone", how="inner")
print("Après jointure avec aliment_avicole :", df_merge["Code zone"].nunique())
df_merge = df_merge.merge(df_surfaceAgricole_complet_jointure, on="Code zone", how="inner")
print("Après jointure avec surfaceAgricole_complet :", df_merge["Code zone"].nunique())
df_finale = df_merge.merge(df_stabilitePolitique_jointure, on="Code zone", how="inner")
print("Après jointure avec stabilitePolitique :", df_finale["Code zone"].nunique())
Base TDI : 166 Après jointure avec taux de croissancePIB : 166 Après jointure avec RNB/hab : 166 Après jointure avec part_avicole : 166 Après jointure avec croissancePopulation : 166 Après jointure avec aliment_avicole : 166 Après jointure avec surfaceAgricole_complet : 166 Après jointure avec stabilitePolitique : 166
df_finale.head()
| Code zone | Pays | Importations - Quantité | TDI_avicole (%) | taux de croissance du PIB (%) | RNB/hab (USD) | Quantité de produits avicoles (kg/hab/an) | Part avicole (%) | CAGR (%/an), 2000-2018 | Aliments avicoles (Milliers de tonnes) | Pop_2017 | Surface agricole par hab (ha/hab) | Stabilité politique | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | Arménie | 36.0 | 42.86 | 9.305043 | 4094.332429 | 27.70 | 48.35 | -0.217251 | 138.0 | 2944791.0 | 0.5692 | -0.63 |
| 1 | 2 | Afghanistan | 83.0 | 63.36 | 4.444345 | 539.263388 | 3.03 | 30.03 | 3.283677 | 188.0 | 36296113.0 | 1.0445 | -2.79 |
| 2 | 3 | Albanie | 38.0 | 37.62 | 9.767331 | 4503.239709 | 31.02 | 49.90 | -0.454795 | 398.0 | 2884169.0 | 0.4071 | 0.37 |
| 3 | 4 | Algérie | 2.0 | 0.30 | 6.287893 | 4027.655361 | 14.81 | 55.93 | 1.724390 | 3973.0 | 41389189.0 | 0.9987 | -0.92 |
| 4 | 7 | Angola | 300.0 | 86.46 | 20.766649 | 3788.156996 | 11.23 | 46.50 | 3.566730 | 789.0 | 29816766.0 | 1.5349 | -0.39 |
j'ai oublié de supprimer la France, donc je le fais ici.
df_finale = df_finale[df_finale["Code zone"]!= 68]
print("Nombre de pays retenu :", df_finale["Code zone"].nunique())
Nombre de pays retenu : 165
Verification NaN
pourcentage_nan = df_finale.isna().sum()/len(df_finale) *100
print(pourcentage_nan)
Code zone 0.0 Pays 0.0 Importations - Quantité 0.0 TDI_avicole (%) 0.0 taux de croissance du PIB (%) 0.0 RNB/hab (USD) 0.0 Quantité de produits avicoles (kg/hab/an) 0.0 Part avicole (%) 0.0 CAGR (%/an), 2000-2018 0.0 Aliments avicoles (Milliers de tonnes) 0.0 Pop_2017 0.0 Surface agricole par hab (ha/hab) 0.0 Stabilité politique 0.0 dtype: float64
3) Analyse exploratoire des données : comprendre ce qu'on a en face de nous¶
a) Description des données "Photo d'ensemble" :
df_finale.info()
<class 'pandas.core.frame.DataFrame'> Index: 165 entries, 0 to 165 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Code zone 165 non-null int64 1 Pays 165 non-null object 2 Importations - Quantité 165 non-null float64 3 TDI_avicole (%) 165 non-null float64 4 taux de croissance du PIB (%) 165 non-null float64 5 RNB/hab (USD) 165 non-null float64 6 Quantité de produits avicoles (kg/hab/an) 165 non-null float64 7 Part avicole (%) 165 non-null float64 8 CAGR (%/an), 2000-2018 165 non-null float64 9 Aliments avicoles (Milliers de tonnes) 165 non-null float64 10 Pop_2017 165 non-null float64 11 Surface agricole par hab (ha/hab) 165 non-null float64 12 Stabilité politique 165 non-null float64 dtypes: float64(11), int64(1), object(1) memory usage: 18.0+ KB
Note, première observation :
On a 165 pays
13 colonnes dont 11 indicateurs
Aucun NaN
Types corrects
df_finale.describe()
| Code zone | Importations - Quantité | TDI_avicole (%) | taux de croissance du PIB (%) | RNB/hab (USD) | Quantité de produits avicoles (kg/hab/an) | Part avicole (%) | CAGR (%/an), 2000-2018 | Aliments avicoles (Milliers de tonnes) | Pop_2017 | Surface agricole par hab (ha/hab) | Stabilité politique | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| count | 165.00000 | 165.000000 | 165.000000 | 165.000000 | 165.000000 | 165.000000 | 165.000000 | 165.000000 | 165.000000 | 1.650000e+02 | 165.000000 | 165.000000 |
| mean | 123.69697 | 104.587879 | 34.472242 | 7.720804 | 13469.461597 | 27.390545 | 48.587394 | 1.392066 | 5101.618182 | 4.372202e+07 | 1.312370 | -0.069455 |
| std | 71.10422 | 223.348519 | 38.389104 | 6.294400 | 17761.607275 | 18.694425 | 19.208446 | 1.225384 | 22746.718042 | 1.561646e+08 | 3.612748 | 0.884375 |
| min | 1.00000 | 0.000000 | 0.000000 | -23.927708 | 454.350854 | 0.560000 | 2.950000 | -1.232440 | 0.000000 | 5.204500e+04 | 0.000700 | -2.930000 |
| 25% | 63.00000 | 4.000000 | 3.240000 | 5.209157 | 1906.725675 | 9.220000 | 34.030000 | 0.514754 | 50.000000 | 2.884169e+06 | 0.188700 | -0.630000 |
| 50% | 119.00000 | 19.000000 | 19.350000 | 7.449328 | 5774.905142 | 27.040000 | 49.330000 | 1.295638 | 552.000000 | 9.785843e+06 | 0.411900 | 0.000000 |
| 75% | 184.00000 | 99.000000 | 61.540000 | 9.906242 | 17175.916365 | 39.120000 | 63.130000 | 2.302551 | 2716.000000 | 2.940248e+07 | 0.932600 | 0.640000 |
| max | 256.00000 | 1333.000000 | 248.610000 | 25.722423 | 81099.824689 | 77.380000 | 90.600000 | 6.435566 | 245001.000000 | 1.421022e+09 | 36.440300 | 1.560000 |
Note, première observation :
Les indicateurs présentent une forte variabilité entre pays. Ces disparités confirment la nécessité de norrmaliser les données et de traiter les outliers avant le clustering.
b) Distribution de chaque variable "comprendre la forme des données pour chaque indicateur" :
import matplotlib.pyplot as plt
import seaborn as sns
cols_to_plot= df_finale.drop(columns=["Code zone","Pays"])
#cols_to_plot.head()
#Histogrammes de toutes les variables numériques
cols_to_plot.hist(figsize=(15,12),bins=30) #bins est le nombre de barre, d'intervalle
plt.suptitle("Distribution des variables (histogrammes)",fontsize=16)
plt.show()
Variables très asymétriques : importations, TDI avicole, RNB/hab, aliments avicoles, population, surface agricole/hab.
Variables plus équilibrées : part avicole, stabilité politique, croissance démographique,croissance PIB, quantité produits avicoles.
-> envisager une normalisation et un traitement des outliers.
#Boxplots pour toutes les variables numériques
#layout (affichage des figures sur 3 colonnes et 4 lignes)
cols=3
rows=4
plt.figure(figsize=(16,4*rows)) #taille des figures
for i, col in enumerate(cols_to_plot.columns,start=1):
ax=plt.subplot(rows,cols,i)
sns.boxplot(x=cols_to_plot[col],orient='h',width=0.6,fliersize=3)
ax.set_title(col,fontsize=10)
ax.grid(axis='x',linestyle=':',linewidth=0.5)
plt.savefig("box_plot_indicateurs.png",dpi=300, bbox_inches="tight")
plt.tight_layout()
plt.show()
#Boxplots log(1+x) pour les variables très skewed
skewed_candidats= ['Importations - Quantité','RNB/hab (USD)','Pop_2017','Aliments avicoles (Milliers de tonnes)','Surface agricole par hab (ha/hab)','TDI_avicole (%)']
skewed_candidats= [c for c in skewed_candidats if c in df_finale.columns]
plt.figure(figsize=(14,3.5*len(skewed_candidats))) #taille des figures
for i, col in enumerate(skewed_candidats,1):
ax=plt.subplot(len(skewed_candidats),1,i)
sns.boxplot(x=np.log1p(cols_to_plot[col]),orient='h', width=0.6, fliersize=3)
ax.set_title(f"{col}- log1p-transformed",fontsize=11)
ax.grid(axis='x',linestyle=':',linewidth=0.5)
plt.savefig("box_plot_normaliser_indicateurs.png",dpi=300, bbox_inches="tight")
plt.tight_layout()
plt.show()
Pour importations, RNB/ hab, aliments avicoles :
Après log(1+x), la compression de l'echelle a "absorbé" les extrêmes. PLus d'outliers visibles, distributions "propres".
Population : Même après log, il reste 4 outliers car ils sont vraiment hors norme démographiquement.
Ici, le log aide mais ne peut pas effacer le fait qu'ils soient hors normes comparés aux autres -> ce sont des "vraies outliers structurels".
Surface ag/hab : Encore beaucoup d'outliers après log. #vu en version sans inverse
Normal aussi : certains pays ont des surfaces agricoles immenses par rapport à leur population (ex: Australie, Canada, Kazakhstan..).
Ce n'est pas du "bruit" mais une réalité géographique.
#statistiques rapides sur les outliers (IQR rule)
def outlier_stats(series):
s = series.dropna()
q1= s.quantile(0.25)
q3= s.quantile(0.75)
iqr= q3 - q1
low= q1 - 1.5 * iqr
high = q3 + 1.5 * iqr
n_out = s[(s<low)|(s>high)].shape[0]
pct_out = 100 * n_out / s.shape[0] if s.shape[0]>0 else 0
return n_out, round(pct_out,2), low, high
for col in cols_to_plot.columns:
n_out, pct_out, low, high = outlier_stats(cols_to_plot[col])
print(f"{col:45s} -> outliers : {n_out:3d} ({pct_out:5.2f}%) | bounds: [{low:.3g},{high:.3g}]")
#df.shape[0] => nb lignes donc nb pays
#df.shape[1] => nb colonnes (pas utile ici)
Importations - Quantité -> outliers : 18 (10.91%) | bounds: [-138,242] TDI_avicole (%) -> outliers : 1 ( 0.61%) | bounds: [-84.2,149] taux de croissance du PIB (%) -> outliers : 19 (11.52%) | bounds: [-1.84,17] RNB/hab (USD) -> outliers : 20 (12.12%) | bounds: [-2.1e+04,4.01e+04] Quantité de produits avicoles (kg/hab/an) -> outliers : 0 ( 0.00%) | bounds: [-35.6,84] Part avicole (%) -> outliers : 0 ( 0.00%) | bounds: [-9.62,107] CAGR (%/an), 2000-2018 -> outliers : 1 ( 0.61%) | bounds: [-2.17,4.98] Aliments avicoles (Milliers de tonnes) -> outliers : 23 (13.94%) | bounds: [-3.95e+03,6.72e+03] Pop_2017 -> outliers : 19 (11.52%) | bounds: [-3.69e+07,6.92e+07] Surface agricole par hab (ha/hab) -> outliers : 18 (10.91%) | bounds: [-0.927,2.05] Stabilité politique -> outliers : 2 ( 1.21%) | bounds: [-2.54,2.54]
#Liste les pays outliers
def get_outliers(df,col):
s= df[col].dropna()
q1= s.quantile(0.25)
q3= s.quantile(0.75)
iqr= q3 - q1
low = q1 - 1.5 * iqr
high = q3 + 1.5 * iqr
outliers = df[(df[col]<low)|(df[col]>high)][["Pays", col]].reset_index(drop=True)
return outliers, (low,high)
#Pays outliers pour Importations : CHANGER SELON LA COLONNE ETUDIER
out_import, bounds_import = get_outliers(df_finale,"Importations - Quantité")
print("Seuils pour Importations - Quantité :", bounds_import)
print(out_import.to_string(index=False))
Seuils pour Importations - Quantité : (-138.5, 241.5)
Pays Importations - Quantité
Angola 300.0
Chine, continentale 452.0
Cuba 313.0
Allemagne 1333.0
Chine - RAS de Hong-Kong 1074.0
Iraq 798.0
Japon 1105.0
Mexique 1040.0
Pays-Bas 880.0
Philippines 253.0
Fédération de Russie 318.0
Arabie saoudite 732.0
Afrique du Sud 516.0
Espagne 246.0
Émirats arabes unis 478.0
Royaume-Uni de Grande-Bretagne et d'Irlande du Nord 880.0
Viet Nam 295.0
Belgique 458.0
Sens, Cohérence des outliers = pas d'erreur de saisie
=> à conserver mais une normalisation doit être effectuée avant clustering.
c) Corrélations entre variables "détecter si certains indicateurs racontent la même histoire"
#Matrice de corrélation
plt.figure(figsize=(12,8))
sns.heatmap(cols_to_plot.corr(), annot=True, cmap="coolwarm", fmt=".2f",vmin= -1, vmax=1, center=0)
plt.title("Matrice de corrélation entre variables", fontsize=14)
plt.savefig("matrice_corr_variable.png",dpi=300, bbox_inches="tight")
plt.show()
d) Scatterplots
#focus sur certaines relations
#TDI vs PIB/hab
sns.scatterplot(data=cols_to_plot,x="RNB/hab (USD)", y="TDI_avicole (%)")
plt.xscale("log") #souvent utile car RNB/hab est très étalé
plt.show()
4) Exportation df_finale¶
df_finale.to_csv("Bouzouita_Hayette_df_finale_p9.csv", index=False)
SUITE : Voir Notebook2