<jupyter_start><jupyter_text>2040 le cap des 100% de voitures électriques *Etude data - Projet 8 - @Nalron (août 2020)*\*Traitement des données sur Jupyter Notebook (Distribution Anaconda)*\*Etude réalisée en langage Python*Visualisation des Tableaux de bord: [Tableau Public](https://public.tableau.com/profile/nalron!/vizhome/ElectricCarsFrance2040/Vuedensemble) ---  Brève description__Les bornes de recharge, condition sine qua non au décollage du véhicule électrique__. L’accès aux bornes de recharge est l'un des principaux freins à l’essor de la voiture électrique. Les initiatives publiques et privées se multiplient pour renforcer le maillage sur l’ensemble du territoire et démocratiser le véhicule électrique. Sur le papier, le nombre de bornes de recharge pour véhicules électriques est suffisant dans l'Hexagone. En réalité, la qualité du réseau et l'absence de bornes dans certaines zones suscitent encore la méfiance des consommateurs. __Un défi majeur est de développer une infrastructure suffisante dans l'Hexagone__, en réponse aux 69 % d'automobilistes français qui estiment que les bornes sont mal positionnées (selon la dernière édition de l'Observatoire Cetelem de l'automobile).Le baromètre publié en 2019 par l'Avere-France et Gireve recensait pourtant près de 28.000 points de recharge ouverts au public sur le territoire (pour près de 200.000 véhicules électriques en circulation), soit une borne pour 7,2 véhicules électriques. « Le maillage actuel est correct : la recommandation européenne préconise un taux d'un pour 10 », reconnaît <NAME>, déléguée générale de l'Avere-France (association nationale pour le développement électrique). Il reste toutefois des zones blanches, comme la Haute-Loire ou la Corse. Autre problème, les bornes de recharge rapide ne représentent que 9 % du total. __N'avons-nous pas une densification du réseau qui ne suit pas la croissance du marché?__ Au-delà des problèmes actuels et sans doute futurs de densité du réseau, les utilisateurs déplorent aussi sa piètre qualité : bornes non branchées, défectueuses, incompatibles avec la voiture… Sans parler de la multiplicité des opérateurs, qui entraîne des tarifs variables et souvent obscurs. Une grande incertitude qui transforme chaque voyage longue distance en aventure! __L'étude a pour objectif de proposer une vue d'ensemble afin de pouvoir étudier, analyser et vérifier les nouveaux usages liés à l’évolution actuelle et future du marché.__ La consommation des véhicules électriques varie en fonction de l’usage et de la vitesse, comme pour les véhicules thermiques. Quant à l’autonomie des voitures en 2040. Comme le confirme le président d’Avere-France, elle devrait disposer d’une autonomie de 500 à 600 km NEDC. Cela correspond à un niveau d’équilibre tant économique (prix des batteries/autonomie) que technique (masse du véhicule/autonomie). C’est aujourd’hui le niveau d’autonomie de voitures haut de gamme, comme les Tesla. Enfin, l'étude menée permet d’appliquer une approche de modélisation et de simulation de ce que sera le marché d'ici 2040, si la data nous le permet. D'autres incertitudes pèsent également dans la balance, comme par exemple : __Le réseau électrique sera-t-il à même de répondre à la demande? Faudra-t-il craindre des blackouts ou la construction de nouvelles centrales nucléaires?__La France est engagée dans un processus de transition énergétique dont un des piliers est la sobriété et l’efficacité énergétique. Le mix énergétique en 2040 : moins de nucléaire et de thermique et plus d'énergies renouvelables. Or, d’importantes économies d’énergie vont être réalisées grâce à l’isolation des logements, la généralisation d’appareils électroménagers moins énergivores ou encore l’élimination des radiateurs électriques au profit de systèmes plus performants (pompe à chaleur) ou non-électriques. ___Des véhicules électriques, des bornes, et du réseau électrique, voyons comment solutionner l'équilibre.___  Rappel : dates et décisions politiques C’est acté ! En 2040, les véhicules roulant à l’essence et au diesel ne seront plus commercialisés.**Extrait du Plan Climat le 6 juillet 2017 :** [Plan Climat](https://www.ecologique-solidaire.gouv.fr/sites/default/files/2017.07.06%20cp_plan_climat.pdf)_"Le Gouvernement prendra l’initiative de proposer au niveau européen une norme Euro 7 ambitieuse et de fixer l’objectif de **mettre fin à la vente de voitures émettant des gaz à effet de serre en 2040**. Il portera cette position aux niveaux européen et international et réunira une coalition de pays pour promouvoir cet objectif (Pays-Bas, Inde…)"_**Les Députés valident la fin des véhicules à énergie fossile pour 2040 :** L’[amendement CD3032](http://www.assemblee-nationale.fr/dyn/15/amendements/1831/CION-DVP/CD3032), adopté le vendredi 17 mai 2019, dresse une feuille de route avec l’objectif pour la France d’atteindre à cette échéance « la décarbonation complète du secteur des transports terrestres », avec 2 paliers intermédiaires.**Pour le premier palier**, le texte à insérer avant l’article 26 A de la loi Lom vise 2030, prévoyant « une hausse progressive de la part des véhicules à faibles et très faibles émissions parmi les ventes de voitures particulières et de véhicules utilitaires légers neufs ». Et ce, avec l’objectif de satisfaire aux exigences européennes en matière de rejets carbonés pour ces véhicules (règlement UE 2019/631) : -37,5% d’émissions de CO2.**C’est le second point intermédiaire**, programmé en 2040, qui met fin à « la vente des voitures particulières et des véhicules utilitaires légers neufs utilisant des énergies fossiles, d’ici à 2040 ». ***Sur leurs comptes Twitter, <NAME>, ministre chargée des Transports, et <NAME>, co-rapporteur du projet de loi d’orientation des mobilités, se réjouissent d’avoir inscrit à ce texte « la neutralité carbone d’ici 2050 ».*** ![Tweets](p8_img/tweets.png)  Les enjeux d'un secteur aux conséquences multiples : Préparer les territoires à la généralisation du véhicule électriqueL'électrification du parc de véhicules va générer une forte pression sur les réseaux de distribution électrique. Pour optimiser la répartition de la charge, la data est appelée à la rescousse. Les territoires devront très certainement être repensés en repositionnant la place de la voiture dans leur urbanisme. Préparer le réseau électriqueQue se passera-t-il demain lorsque ce parc atteindra plusieurs millions de voitures électriques? Le réseau électrique de distribution tiendra-t-il quand, à 19 heures, tout le monde voudra recharger sa batterie?  Préparer les mentalités!Nous tous sommes confronté à l'inconnu, de nouveaux véhicules (voitures électriques autonomes peut-être?), de nouveaux modes de fonctionnement, des changements d'habitude, etc… Bref, une perte de repère qui provoque des craintes, des doutes, des questions qui restent sans réponse, et si seulement nous avions des indicateurs compréhensibles de tous, des cartographies simples, des infos synthétiques pour mieux se faire une idée de ce que nous avons déjà à disposition et de ce que nous pouvons espérer obtenir au cours des prochaines années. ---  Termes utilisés Une **infrastructure de recharge** pour véhicules électriques (**IRVE**) est un ensemble de matériels, tels que circuits d’alimentation électrique, bornes de recharge et points de recharge, coffrets de pilotage et de gestion et de dispositifs utiles notamment à la transmission de données, à la supervision, au contrôle et au paiement, nécessaires au service de la recharge des véhicules électriques. Une infrastructure de recharge est organisée en stations de recharge.Une **station de recharge** (en anglais **Charging Station Pool**) est une zone géographique comportant une borne associée à des emplacements de Archi station borne point Frstationnement ou un ensemble de bornes associées à des emplacements de stationnement, alimentée par un même point de livraison du réseau public dedistribution d’électricité ou par une même installation locale de production ou de stockage d’énergie et exploitée par un seul opérateur.Un **point de recharge** (en anglais **Charging Point ou EVSE**) est une interface qui permet de recharger un seul véhicule électrique à la fois, associée à un emplacement de stationnement. Il comporte au moins un socle pour prise et/ou un câble attaché avec connecteur pour véhicule (cas des recharges rapides).Un **aménageur** est le maitre d’ouvrage d’une infrastructure de recharge jusqu’à sa mise en service et le propriétaire de l’infrastructure dès lors qu’elle est en service.Un **opérateur d’infrastructure de recharge** (acronyme OIR, en anglais **Charging Point Operator ou EVSE Operator**) est la personne qui exploite une infrastructure de recharge pour le compte d’un aménageur dans le cadre d’un contrat, ou pour son propre compte s’il en est l’aménageur, responsable de la production des services aux utilisateurs.Un **opérateur de services de mobilité** (acronyme **OSM**, en anglais **e-Mobility Service Provider ou EMSP**) est un prestataire de services de mobilité pour les utilisateurs de véhicules électriques, incluant des services d’accès à la recharge.![irve](p8_img/irve_illustration.png)source : [AFIREV (ASSOCIATION FRANÇAISE POUR L’ITINÉRANCE DE LA RECHARGE ÉLECTRIQUE DES VÉHICULES)](http://www.afirev.fr/fr/definition-des-termes-de-la-mobilite-electrique/) ---  Protocole et missions [Mission 1 : Positionnement de la voiture électrique en France](https://github.com/nalron/project_electric_cars_france2040/blob/french_version/p8_notebook01.ipynb)Évolution du parc automobile électrique à 2 ans.Identification et classification des inégalités locales des voitures électriques.Autonomie et consommation moyenne d'une voiture électrique. [Mission 2 : Besoin des déploiements en IRVE](https://github.com/nalron/project_electric_cars_france2040/blob/french_version/p8_notebook02.ipynb)Évolution du nombre de points de recharge disponibles ouverts au public.Analyse de la répartition par borne de recharge, type de prise et catégorie d’aménageur.Utilisation des ratios pour le dimensionnement d'un maillage de taille optimale.Prévision du nombre de PDC à horizon 2025. [Mission 3 : Appel de charge au réseau électrique](https://github.com/nalron/project_electric_cars_france2040/blob/french_version/p8_notebook03.ipynb)Analyse de la consommation d'électricité en France et des filières de production.Profiler un pic d’utilisation des bornes de recharge.Courbe de charge réseau électrique pour répondre aux nouveaux modes de consommation. ---  Principales sources des données Données des immatriculations des véhicules : [statistiques.developpement-durable.gouv.fr](https://www.statistiques.developpement-durable.gouv.fr/donnees-sur-les-immatriculations-des-vehicules)Ces résultats présentent des statistiques détaillées sur le nombre de véhicules immatriculés chaque année, neufs ou d'occasion, selon leur type d'énergie pour l'ensemble de la France, par région et par département. Une notice sur la méthodologie des immatriculations est également disponible : [Méthodologie](https://www.statistiques.developpement-durable.gouv.fr/sites/default/files/2020-04/methodologie_donnees_immatriculations_vehicules.pdf)Identifiant du jeu de données : `immatriculation-voitures-neuves-source-energie-localisation`     Tableau comparatif des voitures électriques : [fiches-auto.fr](http://www.fiches-auto.fr/articles-auto/electrique/s-852-comparatif-des-voitures-electriques.php)Les voitures intégralement électriques sur le marché automobile se déclinent sous divers modèles adaptés à des usages tout aussi variés. Grandes, petites, sans permis, sportives, citadines, utilitaires... Voici une sélection des principales autos du marché. Données des bornes de recharge pour véhicules électriques (IRVE) : [data.gouv.fr](https://www.data.gouv.fr/fr/datasets/fichier-consolide-des-bornes-de-recharge-pour-vehicules-electriques/)Fichier consolidé à partir de plusieurs autres sources (voir site référent lien ci-dessus), fournissant des indications de géolocalisation, département, région, opérateur d'exploitation, type de prise, etc…    Identifiant du jeu de données : `fichier-consolide-des-bornes-de-recharge-pour-vehicules-electriques-irve`     Données des points de charge par typologie : [data.enedis.fr](https://data.enedis.fr/explore/dataset/nombre-de-points-de-charge-par-typologie/information/)Le jeu de données a été élaboré par Enedis à partir de ses données propres combinées avec certaines données externes, issues des sociétés Girève et AAA Data. Les données sur les points de charge « particulier » et « société » sont une reconstitution de l’existant construite par Enedis sur la base d’hypothèses. Ces hypothèses s’appuient sur l’évolution du marché du véhicule électrique. Les données, dont le périmètre géographique couvre la France continentale, sont publiées à la maille nationale.Identifiant du jeu de données : `nombre-de-points-de-charge-par-typologie` Parc des installations de production raccordées par departement : [data.enedis.fr](https://data.enedis.fr/explore/dataset/parc-des-installations-de-production-raccordees-par-departement/information/?disjunctive.type_injection)Ce jeu de données permet de visualiser en fonction de la région administrative le parc des différentes filières de production raccordées au réseau de distribution géré par Enedis par tranche de puissance.    Identifiant du jeu de données : `parc-des-installations-de-production-raccordees-par-departement`         Données en puissance sur la consommation et production par filière d'énergie : [rte-france.com](https://www.rte-france.com/fr/eco2mix/eco2mix-telechargement)Données en puissance (temps, réel, consolidées et définitives) : elles concernent la France, les 12 régions administratives et 21 métropoles. Les historiques des données sont corrigés deux fois après leur première publication, au cours du mois suivant, les historiques sont consolidés à partir des données de comptages disponibles, au cours du premier semestre de l’année suivante, les historiques deviennent définitifs à partir de l’ensemble des données de comptages. Données pour les filières nucléaire, gaz, charbon, fioul, hydraulique, éolien, solaire et les bioénergies complétée des rubriques pompage hydraulique et solde des imports/ exports avec l’étranger.    Identifiant du jeu de données = `rte-puissances-*`<jupyter_code>#Import des principales librairies Python
import pandas as pd
import plotly.figure_factory as ff
import requests
import seaborn as sns
%pylab inline<jupyter_output>Populating the interactive namespace from numpy and matplotlib<jupyter_text>Mission 1 : Positionnement de la voiture électrique (VE) en France  Nettoyage des données __`Traitement des données sur les immatriculations des véhicules neufs et d'occasions 2010 à 2019`__<jupyter_code>#Chargement du jeu de données "immatriculation-voitures-neuves-source-energie-localisation"
xls = pd.ExcelFile('p8_data/immatriculation-voitures-neuves-source-energie-localisation.xlsx')
df2010 = pd.read_excel(xls, '2010 ', skiprows=2)
df2011 = pd.read_excel(xls, '2011', skiprows=2)
df2012 = pd.read_excel(xls, '2012', skiprows=2)
df2013 = pd.read_excel(xls, '2013', skiprows=2)
df2014 = pd.read_excel(xls, '2014', skiprows=2)
df2015 = pd.read_excel(xls, '2015', skiprows=2)
df2016 = pd.read_excel(xls, '2016', skiprows=2)
df2017 = pd.read_excel(xls, '2017', skiprows=2)
df2018 = pd.read_excel(xls, '2018', skiprows=2)
df2019 = pd.read_excel(xls, '2019', skiprows=2)
#Visualisation d'un jeu de données
df2011.head()
#Ajout d'une colonne 'Année' par dataframe
df2010['Année'] = 2010
df2011['Année'] = 2011
df2012['Année'] = 2012
df2013['Année'] = 2013
df2014['Année'] = 2014
df2015['Année'] = 2015
df2016['Année'] = 2016
df2017['Année'] = 2017
df2018['Année'] = 2018
df2019['Année'] = 2019
#Concaténation par méthode .concat() des précédents jeux de données
immat_motor_puiss = pd.concat([df2010, df2011, df2012, df2013, df2014, df2015, df2016, df2017, df2018, df2019], 
                               sort=False)
#Premier aperçu du jeu de données 
immat_motor_puiss
#Suppression des lignes dont les valeurs sont manquantes sur l'objet Series 'Départements'
#Suppression de la variable 'Unnamed: 13' non représentative dans l'échantillon
immat_motor_puiss.dropna(subset=['Départements'], axis=0, inplace=True)
immat_motor_puiss.drop(columns=['Unnamed: 13'], inplace=True)
#Renommage des colonnes prenant en compte les puissances de la ligne index 0
immat_motor_puiss.rename(columns={
    'Essence + Superéthanol': 'Essence + Superéthanol < 6CV', 'Unnamed: 3': 'Essence + Superéthanol 6 à 7CV',
    'Unnamed: 4': 'Essence + Superéthanol 8CV et +', 'Electricité-Essence': 'Hybride essence < 6CV',
    'Unnamed: 6': 'Hybride essence 6CV et +', 'Gazole': 'Gazole < 6CV', 'Unnamed: 8': 'Gazole 6CV et +',
    'Essence-GPL': 'Essence-GPL < 6CV', 'Unnamed: 10': 'Essence-GPL 6CV et +', 
    'Gazole-Electricité': 'Hybride gazole', 'Autres et non dét.': 'Autres'
                                  }, inplace=True)
#Réindexation du dataframe
immat_motor_puiss.reset_index(drop=True, inplace=True)
#Affichage des modalités liées aux départements
immat_motor_puiss['Départements'].unique()<jupyter_output><empty_output><jupyter_text>Il est nécessaire de supprimer la modalité 'Total' de la variable 'Départements'.<jupyter_code>#Boucle itérative de suppression de la modalité 'Total'
for i, row in immat_motor_puiss.iterrows():
    if row['Départements'] == 'Total':
        immat_motor_puiss.drop(i, inplace=True)
        

#Autre méthode
'''immat_motor_puiss.drop(immat_motor_puiss[immat_motor_puiss['Départements'] == 'Total']
                        .index, axis=0, inplace = True) 
'''
#Affichage des données
immat_motor_puiss
#Affichage des modalités liées aux régions
immat_motor_puiss['Régions'].unique()<jupyter_output><empty_output><jupyter_text>Les régions sont plus difficiles à gérer, car les observations vont de 2010 à 2019, et la Loi relative à la délimitation des régions de 2014 nous amène à avoir des parts de région en doublons. Dans l'immédiat les observations sont laissées dans l'état, la précision des observations par département est largement privilégiée dans notre contexte.<jupyter_code>#Analyse du type de chaque colonne
immat_motor_puiss.dtypes<jupyter_output><empty_output><jupyter_text>Notons que la plupart des données ne sont pas de type 'float' ou 'int', il est important de modifier ces types de données pour la suite des calculs.<jupyter_code>#Changement du type des Series 'object' en 'float64' afin de faciliter les calculs
immat_motor_puiss[['Essence + Superéthanol < 6CV', 'Essence + Superéthanol 6 à 7CV', 
                    'Essence + Superéthanol 8CV et +', 'Hybride essence < 6CV', 'Hybride essence 6CV et +', 
                    'Gazole < 6CV', 'Gazole 6CV et +', 'Essence-GPL < 6CV','Essence-GPL 6CV et +',
                    'Hybride gazole']] = immat_motor_puiss[['Essence + Superéthanol < 6CV', 
                    'Essence + Superéthanol 6 à 7CV', 'Essence + Superéthanol 8CV et +', 'Hybride essence < 6CV',
                    'Hybride essence 6CV et +', 'Gazole < 6CV', 'Gazole 6CV et +', 'Essence-GPL < 6CV',
                    'Essence-GPL 6CV et +', 'Hybride gazole']].astype(float)
#Visualisation rapide du jeu de données
immat_motor_puiss.head()
#Identification des valeurs manquantes
immat_motor_puiss.isna().sum()<jupyter_output><empty_output><jupyter_text>Rappelons le contexte, le dataframe est constitué de 8 jeux de données traitant des immatriculations des véhicules neufs et d'occassion en France Métropolitaine + Corse de 2010 à 2019. Il peut-être nécessaire d'avoir une vision plus précise sur le positionnement dans le temps et par catégorie de véhicules des observations manquantes.<jupyter_code>#Suppression de la variable 'Autres' qui n'est pas exploitable dans l'état et non représentative 
immat_motor_puiss.drop(columns=['Autres'], inplace=True)
#Visualisation par restriction des valeurs manquantes de la variable 'Hybride essence 6CV et +'
immat_motor_puiss[(immat_motor_puiss['Hybride essence 6CV et +'].isna())]
#Visualisation par restriction des valeurs manquantes de la variable 'Essence-GPL < 6CV'
immat_motor_puiss[(immat_motor_puiss['Essence-GPL < 6CV'].isna())]
#Visualisation par restriction des valeurs manquantes de la variable 'Essence-GPL 6CV et +'
immat_motor_puiss[(immat_motor_puiss['Essence-GPL 6CV et +'].isna())]
#Visualisation par restriction des valeurs manquantes de la variable 'Electricité'
immat_motor_puiss[(immat_motor_puiss['Electricité'].isna())]
#Visualisation par restriction des valeurs manquantes de la variable 'Hybride gazole'
immat_motor_puiss[(immat_motor_puiss['Hybride gazole'].isna())]<jupyter_output><empty_output><jupyter_text>Notons que suivant l'année tous les types de véhicules n'étaient pas ou peu réprensentés suivant la localité. A ce stade de l'étude, les valeurs manquantes peuvent-être laissées en l'état.<jupyter_code>#Agrégation selon les année par fonction .groupby()
immat_motor_puiss_annee = immat_motor_puiss.groupby('Année').sum()
immat_motor_puiss_annee
#Sauvegarde 
immat_motor_puiss_annee.to_csv('p8_datatable/immat_motor_puiss_annee.csv')
#Agrégation selon les départements par fonction .groupby()
immat_motor_puiss_departement = immat_motor_puiss.groupby(['Départements', 'Année']).sum().reset_index()
immat_motor_puiss_departement 
#Vérification des départements identifiés dans le jeu de données final
immat_motor_puiss_departement['Départements'].nunique()<jupyter_output><empty_output><jupyter_text>Notons qu'il y a 96 observations or la France comprend 101 départements. En métropole, leurs indicatifs vont du 01 (Ain) au 95 (Val d'Oise). Une analyse des modalités liées aux départements sera nécessaire. Pour info les 5 départements d'Outre-mer (DOM), non traités dans l'étude, ces indicatifs vont du 971 (Guadeloupe) au 976 (Mayotte). A noter que les indicatifs de la Corse-du-Sud et de la Haute-Corse sont respectivement les 2A et 2B, deux départements pour la Corse qui vient confirmer l'exactitude des 96 observations du jeu de données.<jupyter_code>#Sauvegarde 
immat_motor_puiss_departement.to_csv('p8_datatable/immat_motor_puiss_departement.csv')<jupyter_output><empty_output><jupyter_text>Après avoir effectué quelques essais de visualisation sur logiciel Tableau, notons que le détail des énergies n'est pas nécessaire dans le contexte. Afin d'obtenir une vision dans le temps et par localité plus explicite, les typologies de véhicules doivent-être regroupées en 5 grands types : **Electricité, Essence, Gazole, Hybride, GPL**.<jupyter_code>#Création d'une variable 'Essence'
immat_motor = immat_motor_puiss.copy().reset_index()
immat_motor['Essence'] = immat_motor['Essence + Superéthanol < 6CV']\
                         + immat_motor['Essence + Superéthanol 6 à 7CV']\
                         + immat_motor['Essence + Superéthanol 8CV et +']
#Création d'une variable 'Gazole'
immat_motor['Gazole'] = immat_motor['Gazole < 6CV'] + immat_motor['Gazole 6CV et +']
#Création d'une variable 'Hybride'
immat_motor['Hybride'] = immat_motor['Hybride essence < 6CV']\
                       + immat_motor['Hybride essence 6CV et +']\
                       + immat_motor['Hybride gazole']
#Création d'une variable 'GPL'
immat_motor['GPL'] = immat_motor['Essence-GPL < 6CV'] + immat_motor['Essence-GPL 6CV et +']
#Projection sur les variables globales
immat_motor = immat_motor[['Régions', 'Départements', 'Année', 'Electricité', 'Essence', 'Gazole', 
                           'Hybride', 'GPL', 'Total']]
#Aperçu du jeu de données
immat_motor
#Situation des valeurs manquantes par variable
immat_motor.isna().sum()<jupyter_output><empty_output><jupyter_text>Rappelons que ces 960 observations s'échelonnent sur un timeframe de 2010 à 2019, il est normal d'avoir des NaN suivant le couple motorisation/année, également pouvant s'expliquer par des anomalies de recensement. Rappelons également que l'état des modalités de la variable 'Régions' est le résultat non seulement du remaniement des régions de 2014, mais également de la structuration des données réparties par départements. Dans l'immédiat seule l'approche départementale est pertinente, les modalités liées aux régions peuvent rester sans modification particulière.<jupyter_code>#Affichage des observations par agrégation par Nombre d'immatriculation (sans cumul) selon les années
immat_annee = immat_motor.groupby('Année').sum().astype(int)
immat_annee
immat_annee.reset_index(inplace=True)
immat_annee['Année'] = pd.to_datetime(immat_annee['Année'], format='%Y')
immat_annee['Année'] = pd.date_range(start='31/12/2010', end='31/12/2019', freq ='Y')
#Données des immatriculations par année sans cumul
immat_annee<jupyter_output><empty_output><jupyter_text>Voyons également en cumulé ce que représente ces immatriculations…<jupyter_code>#Sauvegarde 
immat_annee.to_csv('p8_datatable/immat_annee.csv')
#Affichage des observations par agrégation par somme cumulative selon les années
immat_motor_annee = immat_motor.groupby('Année').sum()
immat_motor_annee = immat_motor_annee.cumsum(axis=0).astype(int)
immat_motor_annee
immat_motor_annee.reset_index(inplace=True)
immat_motor_annee['Année'] = pd.to_datetime(immat_motor_annee['Année'], format='%Y')
immat_motor_annee['Année'] = pd.date_range(start='31/12/2010', end='31/12/2019', freq ='Y')
immat_motor_annee<jupyter_output><empty_output><jupyter_text>Pour information, il y a 32,2 millions de voitures particulières en circulation en France (chiffre 2016 de l’INSEE). Retenons que dans le cadre de l'étude, en cumulé de 2010 à 2019, plus de 20 Millions de voitures ont été immatriculées en France Métropolitaire + Corse.<jupyter_code>#Affichage des principales statistiques descriptives
immat_motor_annee.describe()
#Sauvegarde 
immat_motor_annee.to_csv('p8_datatable/immat_motor_annee.csv')
#Affichage des observations par agrégation selon les départements
immat_motor_departement = immat_motor.groupby(['Départements', 'Année']).sum().reset_index()
immat_motor_departement
#Sauvegarde
immat_motor_departement.to_csv('p8_datatable/immat_motor_departement.csv')
#Top 10 des meilleurs départements en 2019 pour les immatriculations VE
immat_motor_departement[immat_motor_departement['Année'] == 2019]\
.sort_values(by='Electricité', ascending=False)[:10]
#Top 10 des meilleurs départements en 2019 pour les immatriculations VH
immat_motor_departement[immat_motor_departement['Année'] == 2019]\
.sort_values(by='Hybride', ascending=False)[:10]<jupyter_output><empty_output><jupyter_text>__`Traitement des données sur la consommation des voitures électriques`__<jupyter_code>#Développement d'un Scraper à l'aide de BeautifulSoup 
#Source des données : http://www.fiches-auto.fr/articles-auto/electrique/s-852-comparatif-des-voitures-electriques.php<jupyter_output><empty_output><jupyter_text>![](p8_04_img/screeshot_fiches-auto.fr.png)<jupyter_code>from bs4 import BeautifulSoup

page = requests.get('http://www.fiches-auto.fr/articles-auto/electrique/s-852-comparatif-des-voitures-electriques.php')
soup = BeautifulSoup(page.content, 'html.parser')
#Test de chargement de la page - Code 200 valide le chargement
page.status_code
#Contenu HTML de la page
print(soup.prettify())
#Extraction des modèles de voitures électriques 
all_results = soup.select('td:nth-child(1)')
results = [r.text.split("<")[0].strip() for r in all_results]
model_list = results[:52]

#Aperçu des données
model_list[:11]
#Extraction de la consommation (kWh/100)
all_results = soup.select('td:nth-child(8)')
results = [r.text.split("<")[0].strip() for r in all_results]
results = [r.text.split("kWh/100")[0].strip() for r in all_results]
conso_list = results[:52]

#Aperçu des données
conso_list[:11]
#Extraction des données de la Batterie Bat.(kWh)
all_results = soup.select('td:nth-child(9)')
results = [r.text.split("<")[0].strip() for r in all_results]
results = [r.text.split("kWh")[0].strip() for r in all_results]
bat_list = results[:52]

#Aperçu des données
bat_list[:11]
#Extraction de l'autonomie (Km)
all_results = soup.select('td:nth-child(10)')
results = [r.text.split("<")[0].strip() for r in all_results]
results = [r.text.split("Km")[0].strip() for r in all_results]
autonomie_list = results[:52]

#Aperçu des données
autonomie_list[:11]
#Extraction de la Puissance charge Max. (kW)
all_results = soup.select('td:nth-child(11)')
results = [r.text.split("<")[0].strip() for r in all_results]
results = [r.text.split("kW")[0].strip() for r in all_results]
puissance_charge_list = results[:52]

#Aperçu des données
puissance_charge_list[:11]
#Suppression des lignes inutiles
[model_list.remove(m) for m in model_list if m == 'Modèles']
[conso_list.remove(m) for m in conso_list if m == 'ConsokWh100km']
[bat_list.remove(m) for m in bat_list if m == 'Bat.']
[autonomie_list.remove(m) for m in autonomie_list if m == 'Autonomie']
[puissance_charge_list.remove(m) for m in puissance_charge_list if m == 'Puiss.ChargeMAX']
#Intégration des données dans un dataframe nommé "data_car"
data_car = pd.DataFrame({
    "Modele": model_list,
    "Conso(kWh/100)": conso_list,
    "Bat.kWh": bat_list,
    "Autonomie(Km)": autonomie_list,
    "Puiss.Charge max(kW)": puissance_charge_list  
}, dtype=float)

data_car.to_csv('p8_datatable/data_car.csv')
data_car
#Enrichissement du jeu de données par l'intégration d'une variable 'Année'
data_car['Année'] = pd.Series({
    0: '2019',
    1: '2013',
    2: '2017',
    3: '2017',
    4: '2017',
    5: '2010',
    6: '2016',
    7: '2018',
    8: '2018',
    9: '2018',
    10: '2018',
    11: '2018',
    12: '2019',
    13: '2019',
    14: '2014',
    15: '2014',
    16: '2019',
    17: '2017',
    18: '2017',
    19: '2018',
    20: '2017',
    21: '2010',
    22: '2013',
    23: '2012',
    24: '2015',
    25: '2018',
    26: '2018',
    27: '2015',
    28: '2017',
    29: '2018',
    30: '2012',
    31: '2019',
    32: '2019',
    33: '2019',
    34: '2017',
    35: '2016',
    36: '2019',
    37: '2018',
    38: '2019',
    39: '2017',
    40: '2016',
    41: '2019',
    42: '2016',
    43: '2019',
    44: '2014',
    45: '2017',
    46: '2013'
})
#Visualisation des données enrichies par l'année des modèles des véhicules électriques
data_car
#Principales statistiques descriptives 
data_car.describe()<jupyter_output><empty_output><jupyter_text>Notons qu'il est "absurbe" d'établir aussi simplement une moyenne d'un type de Batterie, cela doit-être corrélé avec la taille du parc de VE selon leur typologie. Mais ces quelques statistiques descriptives pourront en autre servir à établir des prévisions et des simulations, par exemple l'estimation d'un pic de consommation dans le cas d'un branchement simultané de l'ensemble des voitures électriques, etc…<jupyter_code>#Sauvegarde 
data_car.to_csv('p8_datatable/data_car.csv')
#Agrégation des observations selon l'année par méthode .groupby() 
data_car_year = data_car.groupby('Année')[['Autonomie(Km)', 'Conso(kWh/100)']].mean().round(2).reset_index()
data_car_year
#Sauvegarde 
data_car_year.to_csv('p8_datatable/data_car_year.csv')<jupyter_output><empty_output><jupyter_text>L'autonomie est ici estimée selon la capacité de la batterie et la consommation moyenne à allure inférieure à 120 km/h (peut varier selon conduite, climat). Notez aussi que le nombre inclut le total de la batterie alors que les autos se réservent généralement 5 kWh de sécurité pour éviter une panne à 100% qui induirait que même l'électronique ne puisse plus être alimenté. N'oublions pas non plus qu'on exploite généralement la batterie sur les 20-80% de charge.  Prévision des prochaines immatriculations de voitures électriques à 2 ansL'historique reste de petite taille, idéalement une granularité plus fine /Mois serait plus appropriée. Notons malgré tout qu'une prévision à court terme reste réalisable, essayons l'Algorithme Prophet (from Facebook).<jupyter_code>#Rappel du jeu de données utilisé à des fins de prévision
immat_annee<jupyter_output><empty_output><jupyter_text>Notons que l'échantillon pris pour référence est celui des immatriculations / année en valeurs non cumulées. Toutes les prévisions seront faites à partir des valeurs non cumulées, ensuite sur Tableau les graphiques seront détaillés en cumulé si nécessaire.<jupyter_code>#Préparation des données et chargement de la librairie Prophet
from fbprophet import Prophet
plt.style.use('ggplot')
import warnings
warnings.filterwarnings("ignore")

forecast_prophet_ve = immat_annee.copy()
forecast_prophet_ve = forecast_prophet_ve[['Année', 'Electricité']]

forecast_prophet_ve.rename(columns={'Année': 'ds', 'Electricité': 'y'}, inplace=True)
forecast_prophet_ve
#Sauvegarde 
forecast_prophet_ve.to_csv('p8_datatable/forecast_prophet_ve.csv')
#Instanciation et entrainement du modèle
model = Prophet(weekly_seasonality=False, daily_seasonality=False,  yearly_seasonality=True, n_changepoints=7)
model.fit(forecast_prophet_ve)
#Prévision de l'évolution des immatriculations des Véhicules électriques à 2 ans 
future = model.make_future_dataframe(periods=2, freq='Y')
forecast = model.predict(future)
fig = model.plot(forecast)
fig.savefig('p8_img/forecast_prophet_ve.png')
#Visualisation des données prédictives
forecast_ve = model.predict(future)
forecast_ve[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()
#Préparation des données (observations + prévisions) pour Test statistique
metric_forecast_ve = forecast.set_index('ds')[['yhat', 'yhat_lower', 'yhat_upper']]\
                     .join(forecast_prophet_ve.set_index('ds')).reset_index()

metric_forecast_ve
#Sauvegarde 
metric_forecast_ve.to_csv('p8_datatable/metric_forecast_ve.csv')
#Import des fonctions statistiques from Scikit Learn
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
periods=2 #Prévision ici sur 2 ans
#Calcul du Coef. de détermination
r2_score(metric_forecast_ve['y'][:-periods], metric_forecast_ve['yhat'][:-periods])<jupyter_output><empty_output><jupyter_text>Très bien! Mais voyons les autres coefficients pour avoir une idée plus précise.<jupyter_code>#Calcul du MSE
mean_squared_error(metric_forecast_ve['y'][:-periods], metric_forecast_ve['yhat'][:-periods])
#Calcul du RMSE
math.sqrt(mean_squared_error(metric_forecast_ve['y'][:-periods], metric_forecast_ve['yhat'][:-periods]))<jupyter_output><empty_output><jupyter_text>Une valeur proche de zéro confirme la robustesse du modèle, or ici la valeur est très importante. L'échantillon est de très petite taille, on peut en déduire qu'une prédiction ne sera pas fiable dans le temps, les craintes de départ semblent se confirmer, une granularité par mois aurait été préférable.Maintenant ... voyons à quoi ressemble l'erreur absolue moyenne (MAE).<jupyter_code>#Calcul du MAE
mean_absolute_error(metric_forecast_ve['y'][:-periods], metric_forecast_ve['yhat'][:-periods])<jupyter_output><empty_output><jupyter_text>Les données à disposition ne sont pas suffisantes pour pouvoir établir une modélisation fiable dans le temps. Notons que les prévisions sur une ou deux années semblent aller dans le bon sens, mais dans le contexte rencontré il n'est pas possible de pouvoir établir d'autres prévisions à plus long terme.  Analyse complémentaire a posterioriOn tronque la série de l’année 2019, qu’on cherche ensuite à prévoir à partir de l’historique 2010-2017. Cette analyse permet d'avoir une idée complémentaire de la qualité prédictive du modèle choisi.<jupyter_code>#Données tronquée de l'année 2019
forecast_prophet_ve_trunc = forecast_prophet_ve[:-1]
#Instanciation et entrainement du modèle
model = Prophet(weekly_seasonality=False, daily_seasonality=False, yearly_seasonality=True, n_changepoints=6)
model.fit(forecast_prophet_ve_trunc)

#Prévision de l'évolution des immatriculations des Véhicules électriques a posteriori 12 mois
future = model.make_future_dataframe(periods=1, freq='Y')
forecast = model.predict(future)
fig = model.plot(forecast)
fig.savefig('p8_img/forecast_prophet_ve_posteriori.png')
#Visualisation des 5 dernières années
forecast_ve_trunc = model.predict(future)
display(forecast_ve_trunc[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail())
display(forecast_prophet_ve[len(forecast_prophet_ve)-1:])<jupyter_output><empty_output><jupyter_text>En 2019 nous avons une observation de 42262 voitures électriques immatriculées en France Métropolitaine + Corse, or a posteri le modèle prédictif Prophet nous propose 33120 avec in intervalle de confiance compris entre 31314 et 35044. **On confirme les précédents résultats statistiques, le modèle ne peut pas être robuste dans le temps par manque de données, une fréquence annuelle sur 10 ans n'est pas entièrement satisfaisant. Mais notons qu'en cumulé le modèle se rapproche de la réalité, fin 2019 prévision à 164984 contre 164970, visible sur les représentations graphiques de Tableau.**  Prévision des prochaines immatriculations de voitures hybrides à 2 ans<jupyter_code>#Préparation des données
forecast_prophet_vh = immat_annee.copy()
forecast_prophet_vh = forecast_prophet_vh[['Année', 'Hybride']]

forecast_prophet_vh.rename(columns={'Année': 'ds', 'Hybride': 'y'}, inplace=True)
forecast_prophet_vh
#Sauvegarde 
forecast_prophet_vh.to_csv('p8_datatable/forecast_prophet_vh.csv')
#Instanciation et entrainement du modèle
model = Prophet(weekly_seasonality=False, daily_seasonality=False, yearly_seasonality=True, n_changepoints=7)
model.fit(forecast_prophet_vh)
#Prévision de l'évolution des immatriculations des Véhicules hybrides à 2 ans 
future = model.make_future_dataframe(periods=2, freq='Y')
forecast = model.predict(future)
fig = model.plot(forecast)
fig.savefig('p8_img/forecast_prophet_vh.png')
#Visualisation des 5 dernières années
forecast_vh = model.predict(future)
forecast_vh[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()
#Préparation des données (observations + prévisions) pour Test statistique
metric_forecast_vh = forecast.set_index('ds')[['yhat', 'yhat_lower', 'yhat_upper']]\
                     .join(forecast_prophet_vh.set_index('ds').y).reset_index()

metric_forecast_vh
#Sauvegarde 
metric_forecast_vh.to_csv('p8_datatable/metric_forecast_vh.csv')
#Tests statistiques
print("R2 : " + str((r2_score(metric_forecast_vh['y'][:-periods], metric_forecast_vh['yhat'][:-periods]))))
print("MSE : " + str(mean_squared_error(metric_forecast_vh['y'][:-periods], metric_forecast_vh['yhat'][:-periods])))
print("RMSE : " + str(math.sqrt(mean_squared_error(metric_forecast_vh['y'][:-periods], metric_forecast_vh['yhat'][:-periods]))))
print("MAE : " + str(mean_absolute_error(metric_forecast_vh['y'][:-periods], metric_forecast_vh['yhat'][:-periods])))<jupyter_output>R2 : 0.9535756184835417
MSE : 70953845.25609621
RMSE : 8423.410547758918
MAE : 7637.788770254975<jupyter_text>Notons que les précédentes conclusions sont également rencontrées dans cette modélisation. Il n'est pas utile de tester a posteriori, les mêmes conclusions peuvent-être notées, à savoir que l'échantillon n'est pas représentatif dans le temps, le volume des observations étant très faible. **Mais en cumulé notre modèle prédictif permet d'obtenir un total d'immatriculations à fin 2019 de 549477 vs 549381. Voyons quelle prévision pouvons-nous obtenir sur le déclin du Gazole.**  Prévision des prochaines immatriculations de voitures gazole à 2 ans<jupyter_code>#Préparation des données
forecast_prophet_vg = immat_annee.copy()
forecast_prophet_vg = forecast_prophet_vg[['Année', 'Gazole']]

forecast_prophet_vg.rename(columns={'Année': 'ds', 'Gazole': 'y'}, inplace=True)
forecast_prophet_vg
#Sauvegarde 
forecast_prophet_vg.to_csv('p8_datatable/forecast_prophet_vg.csv')
#Instanciation et entrainement du modèle
model = Prophet(weekly_seasonality=False, daily_seasonality=False, yearly_seasonality=True, n_changepoints=7)
model.fit(forecast_prophet_vg)
#Prévision de l'évolution des immatriculations des Véhicules gazole à 2 ans 
future = model.make_future_dataframe(periods=2, freq='Y')
forecast = model.predict(future)
fig = model.plot(forecast)
fig.savefig('p8_img/forecast_prophet_vg.png')
#Visualisation des 5 dernières années
forecast_vg = model.predict(future)
forecast_vg[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()
#Préparation des données (observations + prévisions) pour Test statistique
metric_forecast_vg = forecast.set_index('ds')[['yhat', 'yhat_lower', 'yhat_upper']]\
                     .join(forecast_prophet_vg.set_index('ds').y).reset_index()

metric_forecast_vg
#Sauvegarde 
metric_forecast_vg.to_csv('p8_datatable/metric_forecast_vg.csv')
#Tests statistiques
print("R2 : " + str((r2_score(metric_forecast_vg['y'][:-periods], metric_forecast_vg['yhat'][:-periods]))))
print("MSE : " + str(mean_squared_error(metric_forecast_vg['y'][:-periods], metric_forecast_vg['yhat'][:-periods])))
print("RMSE : " + str(math.sqrt(mean_squared_error(metric_forecast_vg['y'][:-periods], metric_forecast_vg['yhat'][:-periods]))))
print("MAE : " + str(mean_absolute_error(metric_forecast_vg['y'][:-periods], metric_forecast_vg['yhat'][:-periods])))<jupyter_output>R2 : 0.9587700520367696
MSE : 2873852891.125794
RMSE : 53608.32856120207
MAE : 43720.585635430085<jupyter_text>Idem, même remarques concernant la qualité de cette modélisation, elle ne sera pas forcément représentative dans le temps.<jupyter_code>#Variable de stockage du nombre de VE et VH en valeurs cumulées à fin 2021
ve2021 = int(forecast_ve['yhat'].cumsum().max())
vh2021 = int(forecast_vh['yhat'].cumsum().max())
print('ve2021 : ' + str(ve2021))
print('vh2021 : ' + str(vh2021))<jupyter_output>ve2021 : 247518
vh2021 : 814890
{'fraction_non_alphanumeric': 0.09123254080823136, 'fraction_numerical': 0.030002163617568574, 'mean_word_length': 5.945733845383202, 'pattern_counts': {'":': 5, '<': 115, '<?xml version=': 0, '>': 92, 'https://': 11, 'lorem ipsum': 0, 'www.': 10, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '23', 'dir': 'jupyter-structured-clean-dedup', 'id': '418924', 'license': 'MIT', 'n_tokens_mistral': 15283, 'n_tokens_neox': 14282, 'n_words': 4259, 'path': 'p8_notebook01.ipynb', 'repo_name': 'nalron/project_electric_cars_france2040', 'size': '41621'}