Comparing the first and second wave of COVID-19 in Italy through Python Pandas
By: Angelica Lo Duca
Tags: Second Wave Of Covid 19, Python, Covid 19, Pandas, Data Science

Image by Gerd Altmann from Pixabay

In this tutorial I implement the code to compare some measurements related to the first and second waves in Italy. In my previous post, I dealt with the ratio between the number of total cases and number of swabs. In this post, I consider the following types of measurements:

number of deaths

number of patients admitted to the intensive care

number of number of hospitalized. I exploit the Python pandas library. The code is very simple and reusable thus it can be easily adapted to data related to other Countries.

Every measurement is analysed from two perspectives:

cumulative measure — the measure related to a given day is the sum of all the measurements of the previous days plus the measurement of the current day.

daily measure — the measure related to a given day is given only by the measurement of the previous day.

In addition, for each measurement, I provide the code to compare data related to the first wave with data related to the second wave. I set the 2020, July 31st as the splitting date between the first and second wave.

All the code described in this tutorial is available in my Github repository.

Import data

Firstly, I import data from the Github repository of the Italian Protezione Civile. Data are updated daily. I read the csv file through the read_csv() function and I use the set_index() function to set the date as the index of the dataframe. This operation converts the dataframe into a time series. Then, I use the tail(10) function to show the last 10 rows of the time series.

import pandas as pd

df = pd.read_csv("https://raw.githubusercontent.com/pcm-dpc/COVID-19/master/dati-andamento-nazionale/dpc-covid19-ita-andamento-nazionale.csv")

df.set_index('data', inplace=True)

df.tail(10)

Cumulative measure

I define a generic function, called plot_measure() which plots a measure passed as parameter. This function exploits the matplotblib library to plot the measure.

import matplotlib.pyplot as plt

import numpy as np def plot_measure(measure):

x_labels = []

dates = measure.index.tolist() i = 0

step = 5

while i < len(measure):

x_labels.append(dates[i])

i += step plt.figure(figsize=(25,10))

plt.grid() plt.plot(measure)

plt.xlim(dates[0],dates[len(dates)-1]) plt.xticks(x_labels,rotation=90)

plt.show()

Now I can use the defined function to plot the cumulative number of patients admitted to intensive care (column terapia_intensiva ).

plot_measure(df['terapia_intensiva'])

The same function can be used also to plot all the other columns of the dataframe, such as the total number of hospitalized patients and deaths.

plot_measure(df['totale_ospedalizzati'])

plot_measure(df['deceduti'])

Now I define a function, called plot_measures() which plots two measures, one related to the first wave and the other related to the second wave. The function is very simple and takes the two measures as input.

def plot_measures(measure1, measure2):



plt.figure(figsize=(25,10))

plt.grid() plt.plot(measure1, label='first wave')

plt.plot(measure2, label='second wave')



plt.legend()

plt.show()

In order to split a measure in the two waves, I define a function called overlap() which receives the measure as input, as well as the range of values between min_value and max_value , within the starting date of each wave must be identified. In practice, I'd like that the two waves start when the values of the considered measure fall in the same range of values. For example, for the column terapia_intensiva I'd like that the beginning date of the two waves falls in the interval [400,500]. Then, I create two series, one for each wave and I plot the result.

def overlap(measure, min_value, max_value):

fw_date = measure.where((measure > min_value) & (measure < max_value) ).dropna().index.tolist()[0]



fw_end_date = '2020-07-31T17:00:00'

sw_date = measure[fw_end_date:].where((measure > min_value) & (measure < max_value) ).dropna().index.tolist()[0]





fw_df = measure[fw_date:fw_end_date]



sw_df = measure[sw_date:]



fw_index = np.arange(0, len(fw_df))

sw_index = np.arange(0, len(sw_df))

fw_ts = pd.Series(fw_df.values,index=fw_index)

sw_ts = pd.Series(sw_df.values,index=sw_index)

plot_measures(fw_ts, sw_ts)

Now I can apply the function overlap() to the column terapia_intensiva

overlap(df['terapia_intensiva'], 400, 550)

and the column totale_ospedalizzati

overlap(df['totale_ospedalizzati'], 4900, 5100)

Daily measure

In this case, I define a function called daily_measure() , which calculates the value of the measure related to a given day as the difference between the current value for that day and the value for the previous day. Then the function returns a Series() with the obtained value.

def daily_measure(m):

d_measure = []

for i in range(1, len(m)):

d_measure.append(m[i] - m[i-1])

return pd.Series(d_measure, index=m.index[1:])

I can apply the described function to plot the column terapia_intensiva

plot_measure(daily_measure(df['terapia_intensiva']))

or I can apply the overlap() function to the daily_measure() related to the column terapia_intensiva .

overlap(daily_measure(df['terapia_intensiva']),50,80)

The same analysis can be done for the number of deaths.

plot_measure(daily_measure(df['deceduti']))

overlap(daily_measure(df['deceduti']),180,200)

Summary

In this tutorial I have shown that two kinds of visualizations can be done with data related to COVID-19, one based on cumulative data and the other based on daily data.

In addition, a comparison can be done between the first and second waves of COVID-19. For some analysis regarding the comparison between the first and the second wave, such as predictions and time series analysis, stay tuned and follow me :)

If you wanted to be updated on my research and other activities, you can follow me on Twitter, Youtube and and Github.