Dans ce carnet, j'utiliserai les données disponibles sur: https://www.apple.com/covid19/mobility. Nous nous concentrerons sur la France, mais nous comparerons également les résultats avec ceux de l'Allemagne et de Taiwan pour découvrir l'évolution de la pandémie et le comportement de la population. 05/20/2020
import pandas
import matplotlib.pyplot as plt
import datetime
url = 'https://raw.githubusercontent.com/nshyam97/Apple-Mobility-Trends-Data/master/applemobility.csv'
mobility_data = pandas.read_csv(url, error_bad_lines=False)
Examinons les données du fichier pour obtenir une jauge quant au format et aux données avec lesquelles nous devons travailler et que nous pouvons comparer.
mobility_data.head()
Comme nous pouvons le voir, nous avons un large tableau avec toutes les dates dans des colonnes distinctes. Bien que ce soit probablement le meilleur moyen d'afficher ces données sans que la région et le type de transport soient répétés plusieurs fois, cela ne rend pas le traçage de ces données ou le filtrage à travers ces données très utiles. Il faudra isoler la région et le type de transport puis transposer les colonnes de date pour permettre de tracer.
Premièrement, nous vérifierons quelles régions et quels types de transport nous avons?
mobility_data['transportation_type'].unique()
mobility_data['region'].unique()
mobility_data['region'].nunique()
Nous avons 3 types de transport différents: transit,walking et driving, mais comme nous pouvons le voir au début du tableau, certains endroits ne disposent pas de données de transit. En regardant la région, nous avons un mélange entre les pays et les grandes villes et un total de 152 lieux uniques. Nous verrons quels endroits ont réellement les données de transit.
mobility_data[mobility_data['transportation_type'] == 'transit']
Nous avons 91 sur un total de 152 régions uniques avec des données de transit et elles sont un mélange de pays et de villes. Une lecture rapide montre que seuls les principaux pays et villes ont des données de transit, ce qui est logique car Apple ne disposerait pas de données pour chaque pays ou ville. C'est juste quelque chose à garder à l'esprit pour l'avenir.
Maintenant que nous savons avec quel type de données nous travaillons, nous pouvons commencer à tracer et à comparer différentes villes et pays en utilisant différents types de transport. Nous commencerons par les villes françaises: Paris, Lyon et Toulouse.
Premièrement, nous allons créer une fonction qui prendra la ville ou le pays et le type de transport et créer un bloc de données séparé avec les colonnes de date transposées en lignes séparées et les valeurs correspondantes.
def transpose_df(region_name, transportation):
df = mobility_data[(mobility_data['region'] == region_name) &
(mobility_data['transportation_type'] == transportation)]
df = df.drop(['geo_type', 'alternative_name'], axis=1)
df_t = df.melt(['region', 'transportation_type'], var_name='Date', value_name='Value')
df_t.Date = pandas.to_datetime(df_t.Date, format='%Y-%m-%d')
df_t.set_index('Date', inplace=True)
df_t.Value = df_t.Value - df_t.Value.iloc[0]
df_t.Value = df_t.Value.round(2)
return df_t
Maintenant que nous avons cette fonction, nous pouvons l'utiliser pour créer des blocs de données pour chacune de nos villes françaises afin que nous puissions les comparer graphiquement. Nous utiliserons d'abord le type de transport «walking» pour les comparer tous.
france = transpose_df('France', 'walking')
paris = transpose_df('Paris', 'walking')
lyon = transpose_df('Lyon', 'walking')
toulouse = transpose_df('Toulouse', 'walking')
paris.head()
Nous avons maintenant une seule colonne de données avec toutes les dates sous forme de lignes et leurs valeurs correspondantes dans la colonne "Value". Nous conservons également les colonnes de région et de type de transport, ce qui cause beaucoup de duplication, mais j'ai pensé qu'il valait mieux les conserver là au cas où quelqu'un reverrait ce bloc de données plus tard dans le code et voulait savoir ce qu'il montrait. Ces colonnes peuvent tout aussi bien être supprimées.
Avant de tracer ces données, il est important de définir ce que les valeurs signifient réellement et pourquoi nous avons soustrait chaque valeur par la première valeur. Sur le site Web Apple Mobility Trends Report, mentionné ci-dessus, nous voyons que la valeur correspond au "nombre relatif de demandes de directions par pays / région ou ville par rapport à un volume de référence au 13 janvier 2020". Si nous regardons en arrière la vue initiale des données lorsque nous les avons chargées pour la première fois, la ligne de base a commencé à 100 et donc en soustrayant 100 de chaque valeur, nous pouvons afficher le graphique comme le pourcentage de changement par rapport à la ligne de base.
Nous pouvons maintenant tracer ces données.
data = [france, paris, lyon, toulouse]
fig=plt.figure(figsize=(10, 6), dpi= 100, facecolor='w', edgecolor='k')
for frame in data:
plt.plot(frame.index, frame['Value'], label=frame['region'][0])
plt.legend()
plt.xlabel('Date')
plt.xticks(rotation=45)
plt.ylabel('Changement en pourcentage des demandes de direction (%)')
plt.title('Apple Mobility Trend Data pour ' + data[0]['transportation_type'][0])
plt.axvline(pandas.Timestamp('2020-03-17'), color='black')
plt.axvline(pandas.Timestamp('2020-02-25'), color='red')
plt.show()
Dans le graphique, nous pouvons observer le comportement des utilisateurs français liés à leurs requêtes d'adresses pendant qu'ils marchaient vers leur destination, on peut voir comment la période précédant au confinement présente un schéma d'augmentation jusqu'à ce qu'ils descendre rapidement lors de l'initiation du confinament le 17 mars.
Maintenant, avec les données structurées, nous pouvons comparer les enregistrements de décès COVID-19 disponibles auprès du John Hopkins Institute pour découvrir leur relation avec les données sur les tendances de la mobilité disponibles pour la France mais aussi pour l'Allemagne et Taïwan.
url='https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_global.csv'
corona_data=pandas.read_csv(url, error_bad_lines=False)
corona_data.head()
Comme nous pouvons le voir, le format de ces données est très similaire au format que nous avions auparavant avec les dates toutes définies comme colonnes et les pays et régions comme lignes distinctes. Cela signifie que nous pourrions utiliser une version modifiée de la fonction transpose_df que nous avons créée ci-dessus pour convertir ce tableau dans un format plus utilisable.
corona_data[corona_data['Country/Region'] == 'France']
Nous sélectionnerons celui consolidé pour la France et nous comparerons les données de mobilité dans un graphique
fr_row = corona_data[(corona_data['Country/Region'] == 'France') & (corona_data['Province/State'].isna())]
fr_row
Now that we have the row that we need, we can use a modified function from the one I have created earlier to get the data into a usable format for plotting. One thing also to note is that the dates are in mm/dd/yy format as opposed to the YYYY-mm-dd format used above. We will need to fix this as well.
def transpose_corona_row(df):
df = df.drop(['Province/State', 'Lat', 'Long'], axis=1)
df_t = df.melt(['Country/Region'], var_name='Date', value_name='Value')
df_t.Date = pandas.to_datetime(df_t.Date)
df_t.set_index('Date', inplace=True)
return df_t
FR_deaths = transpose_corona_row(fr_row)
FR_deaths
Nous avons les données dans le bon format, nous pouvons tracer les variables de mobilité et de décès sur le même graphique pour voir leur évolution et voir comment les choses évoluent avec l'augmentation du nombre de décès en France.
FR_walking = transpose_df('France', 'walking')
FR_driving = transpose_df('France', 'driving')
FR_transit = transpose_df('France', 'transit')
fig, ax1 = plt.subplots(figsize=(10, 6), dpi=100)
color = 'tab:red'
ax1.set_xlabel('Date')
ax1.set_xticklabels(ax1.get_xticklabels(), rotation=45)
ax1.set_ylabel('Changement en pourcentage des demandes de direction (%)', color=color)
ax1.plot(FR_walking.index, FR_walking['Value'], label='Walking', color='purple')
ax1.plot(FR_driving.index, FR_driving['Value'], label='Driving', color='green')
ax1.plot(FR_transit.index, FR_transit['Value'], label='Transit', color='orange')
ax1.legend(bbox_to_anchor=(0.9,1), loc='upper right')
ax1.tick_params(axis='y', labelcolor=color)
ax2 = ax1.twinx()
color = 'tab:blue'
ax2.set_ylabel('Décès confirmés (cumulatifs)', color=color)
ax2.plot(FR_deaths.index, FR_deaths['Value'], color=color)
ax2.tick_params(axis='y', labelcolor=color)
fig.tight_layout()
plt.axvline(pandas.Timestamp('2020-03-17'), color='black')
plt.axvline(pandas.Timestamp('2020-02-25'), color='red')
plt.title('Apple Mobility Trend Data par rapport aux décès cumulés au COVID-19 en France')
plt.show()
Nous pouvons voir que les décès en France commençaient à peine à augmenter lorsque le confinement est entré en vigueur et peu de temps après, le nombre de décès a augmenté de façon exponentielle tandis que la réduction des demandes de mobilité a considérablement diminué, mais il semble que cela n'ait pas eu l'effet souhaité en autorités sanitaires, on retrouve également ce même scénario à Paris, en Allemagne et à Taiwan.
Il convient également de voir la différence entre le premier décès dans le pays (ligne rouge) et le début du confinement (ligne noire), 21 jours se sont écoulés.
PR_walking = transpose_df('Paris', 'walking')
PR_driving = transpose_df('Paris', 'driving')
PR_transit = transpose_df('Paris', 'transit')
fig, ax1 = plt.subplots(figsize=(10, 6), dpi=100)
color = 'tab:red'
ax1.set_xlabel('Date')
ax1.set_xticklabels(ax1.get_xticklabels(), rotation=45)
ax1.set_ylabel('Changement en pourcentage des demandes de direction (%)', color=color)
ax1.plot(PR_walking.index, PR_walking['Value'], label='Walking', color='purple')
ax1.plot(PR_driving.index, PR_driving['Value'], label='Driving', color='green')
ax1.plot(PR_transit.index, PR_transit['Value'], label='Transit', color='orange')
ax1.legend(bbox_to_anchor=(0.9,1), loc='upper right')
ax1.tick_params(axis='y', labelcolor=color)
ax2 = ax1.twinx()
color = 'tab:blue'
ax2.set_ylabel('Décès confirmés (cumulatifs)', color=color)
ax2.plot(FR_deaths.index, FR_deaths['Value'], color=color)
ax2.tick_params(axis='y', labelcolor=color)
fig.tight_layout()
plt.axvline(pandas.Timestamp('2020-03-17'), color='black')
plt.axvline(pandas.Timestamp('2020-02-25'), color='red')
plt.title('Apple Mobility Trend Data par rapport aux décès cumulés au COVID-19 à Paris')
plt.show()
AL_row = corona_data[(corona_data['Country/Region'] == 'Germany') & (corona_data['Province/State'].isna())]
AL_row
AL_deaths = transpose_corona_row(AL_row)
AL_deaths
AL_walking = transpose_df('Germany', 'walking')
AL_driving = transpose_df('Germany', 'driving')
AL_transit = transpose_df('Germany', 'transit')
fig, ax1 = plt.subplots(figsize=(10, 6), dpi=100)
color = 'tab:red'
ax1.set_xlabel('Date')
ax1.set_xticklabels(ax1.get_xticklabels(), rotation=45)
ax1.set_ylabel('Changement en pourcentage des demandes de direction (%)', color=color)
ax1.plot(AL_walking.index, AL_walking['Value'], label='Walking', color='purple')
ax1.plot(AL_driving.index, AL_driving['Value'], label='Driving', color='green')
ax1.plot(AL_transit.index, AL_transit['Value'], label='Transit', color='orange')
ax1.legend(bbox_to_anchor=(0.9,1), loc='upper right')
ax1.tick_params(axis='y', labelcolor=color)
ax2 = ax1.twinx()
color = 'tab:blue'
ax2.set_ylabel('Décès confirmés (cumulatifs)', color=color)
ax2.plot(AL_deaths.index, AL_deaths['Value'], color=color)
ax2.tick_params(axis='y', labelcolor=color)
fig.tight_layout()
plt.axvline(pandas.Timestamp('2020-03-09'), color='red')
plt.title('Apple Mobility Trend Data par rapport aux décès cumulés au COVID-19 en Allemagne')
plt.show()
Dans ce cas, la mobilité a diminué depuis le premier rapport de décès, puis la mobilité a augmenté.
TW_row = corona_data[(corona_data['Country/Region'] == 'Taiwan*') & (corona_data['Province/State'].isna())]
TW_row
TW_deaths = transpose_corona_row(TW_row)
TW_deaths
TW_walking = transpose_df('Taiwan', 'walking')
TW_driving = transpose_df('Taiwan', 'driving')
TW_transit = transpose_df('Taiwan', 'transit')
fig, ax1 = plt.subplots(figsize=(10, 6), dpi=100)
color = 'tab:red'
ax1.set_xlabel('Date')
ax1.set_xticklabels(ax1.get_xticklabels(), rotation=45)
ax1.set_ylabel('Changement en pourcentage des demandes de direction (%)', color=color)
ax1.plot(TW_walking.index, TW_walking['Value'], label='Walking', color='purple')
ax1.plot(TW_driving.index, TW_driving['Value'], label='Driving', color='green')
ax1.plot(TW_transit.index, TW_transit['Value'], label='Transit', color='orange')
ax1.legend(bbox_to_anchor=(0.9,1), loc='upper right')
ax1.tick_params(axis='y', labelcolor=color)
ax2 = ax1.twinx()
color = 'tab:blue'
ax2.set_ylabel('Décès confirmés (cumulatifs)', color=color)
ax2.plot(TW_deaths.index, TW_deaths['Value'], color=color)
ax2.tick_params(axis='y', labelcolor=color)
fig.tight_layout()
plt.axvline(pandas.Timestamp('2020-03-17'), color='black')
plt.title('Apple Mobility Trend Data par rapport aux décès cumulés au COVID-19 à Taiwan')
plt.show()
Un cas totalement différent à Taiwan où la mobilité n'a pas diminué de manière aussi drastique par rapport aux valeurs antérieures au premier décès dans ce pays le 16 février
Les résultats nous permettent de voir le potentiel des données dans l'analyse de la pandémie, il est évident que la mobilité n'est qu'une partie de toutes les ressources qui ont été considérées pour freiner le nombre de décès, dans certains cas extrêmes, les mesures de restriction des mouvements ils ne sont pas aussi efficaces que dans d'autres pays, cependant il est nécessaire de préparer une meilleure analyse en considérant le début des cas et de le comparer avec d'autres mesures prises comme le nombre de tests, les caractéristiques sociales et d'autres facteurs qui diminuent le nombre des décès.
En tant que première approximation de l'analyse du comportement social, les données nous donnent une idée de la façon dont les sociétés Apple et Google capturent nos données et les utilisent pour analyser leurs marchés.