import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
ce sujet vise à acquérir et mettre en forme les données du COVID pour pouvoir produire facilement des diagrammes comme celui-ci
comme vous le voyez on a choisi:
- une liste de pays,
- une liste de mesures - ici: deaths & confirmed,
- et une plage de temps spécifique
les données de Johns Hopkins¶
# le repo github - si vous êtes curieux
official_url = "https://github.com/CSSEGISandData/COVID-19"
autre jeu de données intéressant¶
# le repo qui va vraiment vous servir, avec le fichier json
json_url = "https://pomber.github.io/covid19/timeseries.json"
le format json
?¶
format json
pour le covid¶
acquisition des données json
¶
avec pd.read_json
¶
caching avec requests
¶
en utilisant la librairie requests
on peut implémenter un caching pour nos données
→ requests.get pas à pas
le module requests
permet de récupérer des fichiers sur Internet
utiliser cette approche permet de toujours avoir des données récentes
mais demande une bonne connexion à Internet
sinon allez à la slide (l’encadré) suivante qui utilise des données figées
requests
n’est pas dans la librairie standard
il faut donc l’installer comme d’habitude avec pip
(on fait comment déjà ?)
une fois que c’est fait on peut l’importer
import requests
avec la fonction requests.get
on envoie la requête d’une URL
et on reçoit une réponse
attention la requête suivante (requests.get
) demande une bonne connexion
ou beaucoup de patience...
json_url = "https://pomber.github.io/covid19/timeseries.json"
response = requests.get(json_url)
on peut vérifier que l’échange s’est bien passé
response.ok
-> True
la méthode json()
sur l’objet Response
décode le format JSON
et renvoie les données prêtes pour des traitements en Python
by_country = response.json()
on voit bien une structure Python de dict
et de list
correspondant au contenu du fichier json
vu ci-dessus
by_country
-> {'Afghanistan': [
{'date': '2020-1-22', 'confirmed': 0, 'deaths': 0,'recovered': 0},
{'date': '2020-1-23', 'confirmed': 0, 'deaths': 0, 'recovered': 0},
{'date': '2020-1-24', 'confirmed': 0, 'deaths': 0, 'recovered': 0},
...
si votre connexion ne vous permet pas la requête
voir la prochaine cellule de cours
# pensez à bien installer le module requests
import requests
json_url = "https://pomber.github.io/covid19/timeseries.json"
by_country = None
# mettez cette variable à True si vous avez une bonne connexion
good_connection = False
#good_connection = True
# le code UNIQUEMENT SI VOUS AVEZ UNE BONNE CONNEXION INTERNET
if good_connection:
response = requests.get(json_url)
print(response.ok)
by_country = response.json()
print(type(by_country))
else:
print('pas bonne connexion - pas grave...')
pas bonne connexion - pas grave...
chargement avec la lib json
¶
# le code
if by_country is not None:
print('on utilise les données déjà chargées')
else:
import json
json_file = 'data/covid-frozen.json'
with open(json_file) as f:
by_country = json.load(f)
print(type(by_country))
<class 'dict'>
# regardons un peu la première clé de ce dictionnaire
# les 4 premières clés
list(by_country.keys())[:4]
['Afghanistan', 'Albania', 'Algeria', 'Andorra']
une dataframe globale¶
qui consolide les données covid monde
exercice (version avancé)¶
# votre code
# rangez votre résultat dans la variable global_df
# global_df = ...
exercice (méthode pas-à-pas)¶
# votre code
# votre code
# votre code
# votre code
# votre code
index de la dataframe globale¶
les index ne sont pas forcément uniques¶
si vous avez appelé pd.concat()
sans paramètre particulier, vous pouvez sans doute observer ceci:
# si on essaie d'accéder à la ligne d'index 0
# on remarque qu'en fait on obtient .. plein de lignes
global_df.loc[0]
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[15], line 3
1 # si on essaie d'accéder à la ligne d'index 0
2 # on remarque qu'en fait on obtient .. plein de lignes
----> 3 global_df.loc[0]
NameError: name 'global_df' is not defined
les dates en pandas
¶
# le code
d = pd.to_datetime('2020-12-22')
print(d.year, # 2020
d.month, # 12
d.day) # 22
2020 12 22
les formats de dates en pandas
¶
# sans indication ça peut être ambigu
pd.to_datetime('2020-1-2').day
2
# c'est parfois nécessaire de bien préciser le format
pd.to_datetime('2020-1-2', format='%Y-%d-%m').day
1
# mais sinon c'est très flexible
pd.to_datetime('2021'), pd.to_datetime('aug 2021'),
(Timestamp('2021-01-01 00:00:00'), Timestamp('2021-08-01 00:00:00'))
# .. très flexible
pd.to_datetime('15 july 2021'), pd.to_datetime('15 july 2021 08:00')
(Timestamp('2021-07-15 00:00:00'), Timestamp('2021-07-15 08:00:00'))
convertissons nos dates¶
reprenons à partir de la dataframe globale
# votre code
# votre code
# votre code
# votre code
# votre code
un index plus idoine¶
à présent on va pouvoir choisir un index un peu plus adapté à nos données
# votre réponse
# votre code
accéder via un MultiIndex¶
# votre code
# votre code
# votre code
un exemple de slicing (très) avancé¶
# ce qui nous donne le code suivant
# plutôt subtil, mais vraiment puissant
### pour slicer sur les deux composantes de l'index
# NB: si on voulait tous les pays on pourrait faire
# countries = slice(None)
# qui est équivalent à utiliser ::
# sauf qu'à nouveau ce n'est pas possible syntaxiquement ici
countries = ['France', 'Italy']
time_slice = slice('july 2021', '15 aug 2021')
clean_df.loc[
# les lignes: c'est un 2-index donc on peut passer 2 slices
(countries, time_slice),
# les colonnes: on les veut toutes
:]
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[31], line 13
10 countries = ['France', 'Italy']
11 time_slice = slice('july 2021', '15 aug 2021')
---> 13 clean_df.loc[
14 # les lignes: c'est un 2-index donc on peut passer 2 slices
15 (countries, time_slice),
16 # les colonnes: on les veut toutes
17 :]
NameError: name 'clean_df' is not defined
dessinons¶
plot d’une dataframe¶
# illustration
# 3 colonnes donc 3 courbes
# 4 lignes donc 4 points sur chaque courbe
df = pd.DataFrame(
{'a': [0, 10, 20, 30], 'b': [5, 10, 15, 25], 'c': [30, 15, 5, 0]},
index = ['early', 'before', 'now', 'predicted'],
)
df
# remarquez que pour toutes les courbes,
# c'est toujours l'index qui sert d'abscisse
df.plot();

sur un pays¶
# votre code
# votre code
plusieurs pays¶
il nous reste maintenant à traiter le cas de plusieurs pays
# votre code
# votre code
mise en forme des données¶
df.unstack()
¶
# le code du unstack
# df6 = df3.unstack(0)
# df6
ne reste qu’à plotter¶
# que du coup il n'y a plus qu'à plotter
#
# à vous