import json
import requests
import datetime as dt
from IPython.display import display, Math, Latex
import plotly.graph_objects as go
import plotly.offline as pyo
pyo.init_notebook_mode()
Recentemente (dal 5 Aprile 2020) la variazione giornaliera di ricoverati per COVID-19 (con sintomi o in terapia intensiva) è minore di zero, ovvero la quantità di ricoverati attuali è minore di giorno in giorno.
Questo è sicuramente un dato positivo ma è necessario anche monitorare il numero giornaliero di nuovi ricoveri dato che la variazione giornaliera di ricoverati dipende sia dal numero di nuovi ricoveri che dal numero di nuovi dimessi (in precedenza ricoverati) e di nuovi decessi.
Il numero di nuovi ricoveri è anch'esso in diminuzione?
A quanto ammonta la percentuale di ricoveri rispetto al totale dei casi?
I pazienti in isolamento domiciliare sono guariti? O sono conteggiati come infetti non guariti?
Analizziamo la situazione, definendo e risolvendo il problema.
Sia dato un insieme $\mathbf{P}$ che all'istante $t_0$ contiene $P_0$ elementi.
In ogni istante $t$ sappiamo:
Dunque $P_t$ è un dato istantaneo mentre $R_t$ è un dato cumulativo, ovvero:
$P_i \in \mathbb{N}$
$R_i \in \mathbb{N}^+ , \; R_i = \sum_{t=0}^{i} \Delta R_{t}$
Quindi la differenza di elementi contenuti in $\mathbf{P}$ tra $t_i$ e $t_{i-1}$ è:
$\Delta P_i = P_i - P_{i - 1} \in \mathbb{Z}$
e la differenza di elementi rimossi da $\mathbf{P}$ tra $t_i$ e $t_{i-1}$ è:
$\Delta R_i = R_i - R_{i - 1} \in \mathbb{N}$
inoltre
$\Delta R_i >= P_i$
ovvero in ogni istante $t_i$ non possono essere rimossi da $\mathbf{P}$ più elementi di quanti ne contenga.
Calcoliamo quanti elementi $S_t$ di $\mathbf{P}$ sono stati aggiunti tra $t_0$ e $t$ e quanti elementi $\Delta S_i$ sono aggiunti a $\mathbf{P}$ in ogni istante $t_i$, dove
$\Delta S_i \in \mathbb{N}$
ovvero la quantità di elementi aggiunti a $\mathbf{P}$ in $t_i$ può solo essere $\Delta S_i>=0$
In ogni istante $t_i$ possiamo dire che la somma delle differenze tra gli elementi contenuti in $\mathbf{P}$ e quelli rimossi equivale alla quantità $\Delta S_i$ di elementi aggiunti in $t_i$, ovvero:
$\Delta S_i = \Delta P_i + \Delta R_i$
e, date le premesse, possiamo dunque porre la condizione
$\Delta S_i \in \mathbb{N} \Rightarrow \Delta P_i + \Delta R_i >= 0$
Supponiamo che $\mathbf{P}$ in $t_{i-1}$ contenga $P_{i-1}=25$ e che in tutto (da $t_0$ a $t_{i-1}$) ne siano stati rimossi $R_{i-1} = 2$, mentre in $t_i$ sappiamo che $\mathbf{P}$ ne contiene $P_i=22$ e $R_i=10$ ne sono stati rimossi (da $t_0$ a $t_i)$.
$\Delta P_i = P_i - P_{i - 1} = 22 - 25 = -3$
$\Delta R_i = R_i - R_{i - 1} = 10 - 2 = 8$
Quindi in $t_i$, $\mathbf{P}$ contiene $3$ elementi in meno rispetto a $t_{i-1}$ ma ne sono stati rimossi $8$, dunque devono esserne stati aggiunti $5$ in tutto in $t_i$
$\Delta S_i = \Delta P_i + \Delta R_i = -3 + 8 = 5$
Supponiamo ora invece che $\mathbf{P}$ in $t_{i-1}$ contenga $P_{i-1}=25$ elementi e in tutto (da $t_0$ a $t_{i-1}$) ne siano stati rimossi $R_{i-1} = 2$, mentre in $t_i$ sappiamo che $\mathbf{P}$ contiene $P_i=22$ elementi e $R_i=11$ ne siano stati rimossi (da $t_0$ a $t_i)$.
$\Delta P_i = P_i - P_{i - 1} = 22 - 25 = -3$
$\Delta R_i = R_i - R_{i - 1} = 11 - 10 = 1$
ne deriverebbe che
$\Delta S_i = \Delta P_i + \Delta R_i = -3 + 1 = -2$
ovvero in $t_i$ sarebbero stati aggiunti $-2$ elementi, il che è impossibile e contraddice le premesse
$\Delta P_i >= - \Delta R_i$
dunque, nel caso in cui all'istante $t_i$ non fosse assicurata questa condizione, ci troveremmo di fronte ad un errore nei dati.
A questo punto possiamo dire che:
Se $\Delta P_i > - \Delta R_i$ sono stati aggiunti degli elementi in $t_i$ e che
la quantità cumulativa di tutti gli elementi aggiunti a $\mathbf{P}$ da $t_0$ a $t$ (a prescindere se appartengano ancora a $\mathbf{P}$ o ne siano stati rimossi) sarà pari a:
$$S_t = \sum_{i=0}^{t} \Delta S_i $$NOTA BENE!
Se nel giorno $t_i$ il numero di pazienti ricoverati $P_i$ è diminuito rispetto al giorno precedente ovvero $\Delta P_i < 0$ ma nello stesso giorno $t_i$ sono stati dimessi o sono deceduti in totale $R_i$ tali per cui $\Delta P_i > - \Delta R_i$ significa che il giorno $t_i$ sono comunque stati ricoverati $\Delta S_i = \Delta P_i + \Delta R_i > 0$ pazienti!
json_ita = "https://raw.githubusercontent.com/pcm-dpc/COVID-19/master/dati-json/dpc-covid19-ita-andamento-nazionale.json"
with requests.get(json_ita) as req:
data = json.loads(req.content.decode('utf-8-sig'))
Definiamo $t_0$, il giorno del primo dato acquisito:
print("t0: {}".format(data[0]["data"].replace("T", " ")))
print("t: {}".format(data[-1]["data"].replace("T", " ")))
period = (
dt.datetime.strptime(data[-1]["data"], "%Y-%m-%dT%H:%M:%S") -
dt.datetime.strptime(data[0]["data"], "%Y-%m-%dT%H:%M:%S")
).days
print("∆t: {} days".format(period))
print("CURRENT DATE IS: {}".format(dt.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
Controlliamo che per ogni giorno $t_i$ sia rispettata la condizione
$\Delta P_i + \Delta R_i >= 0$
x = []
P = []
dP = []
R = []
dR = []
S = []
dS = []
totali = []
isolati = []
for i, day in enumerate(data):
date = dt.datetime.strptime(day["data"], "%Y-%m-%dT%H:%M:%S")
x.append(date)
if not i:
P.append(day["ricoverati_con_sintomi"] + day["terapia_intensiva"])
dP.append(day["ricoverati_con_sintomi"] + day["terapia_intensiva"])
R.append(day["dimessi_guariti"] + day["deceduti"])
dR.append(day["dimessi_guariti"] + day["deceduti"])
S.append(P[i] + R[i])
dS.append(S[i])
totali.append(day["totale_casi"])
isolati.append(day["isolamento_domiciliare"])
print("CONDIZIONI INIZIALI")
print(r"t_0={}, P_0={}, R_0={}".format(x[i].strftime("%Y/%m/%d"), P[i], R[i]))
print(r"S_0 = {}".format(S[i]))
print("-------------------------------")
continue
P.append(day["ricoverati_con_sintomi"] + day["terapia_intensiva"])
dP.append(P[i] - P[i - 1])
R.append(day["dimessi_guariti"] + day["deceduti"])
dR.append(R[i] - R[i - 1])
dS.append(dP[i] + dR[i])
S.append(dS[i] + S[i - 1])
totali.append(day["totale_casi"])
isolati.append(day["isolamento_domiciliare"])
print("t_i={} P_i={} R_i={}".format(x[i].strftime("%Y/%m/%d"), P[i], R[i]))
print("S_i = {}".format(S[i]))
if (dP[i] + dR[i]) >= 0:
print(r"∆S_i = {} + {} = {} >= 0".format(dP[i], dR[i], dS[i]))
print("\033[42m OK! \033[0m")
else:
print(r"∆S_i = {} + {} = {} >= 0".format(dP[i], dR[i], dS[i]))
print("\033[41;37m ERR \033[0m")
print("-------------------------------")
Ora guardiamo quanti nuovi pazienti $\Delta S_i$ sono stati ricoverati ogni giorno $t_i$ e confrontiamo questo dato con la differenza giornaliera $\Delta P_i$ di pazienti attualmente ricoverati in $t_i$
fig = go.Figure(data=go.Scatter(
x=x, y=dS,
mode='lines+markers',
marker_color="blue", marker_size=5, marker_symbol="circle", marker_line_width=1,
line_shape='spline',
name="nuovi"
))
fig.add_trace(
go.Scatter(
x=x, y=dP,
mode='lines',
line={"dash": "dot"}, line_shape='spline',
name="attuali"
)
)
fig.update_layout(legend_orientation="h",
showlegend=True, plot_bgcolor='rgba(0,0,0,0)',
yaxis={"gridcolor": '#bdbdbd', "zerolinecolor": '#969696'},
xaxis={"gridcolor": '#bdbdbd'},
title={"text": "ITALIA (nuovi ricoverati giornalieri)", "xanchor": "center", "x": 0.5},
yaxis_title="numero/giorno",
hovermode="x unified"
)
pyo.iplot(fig)
È evidente che, nonostante la differenza di pazienti attualmente ricoverati dal 5 Aprile sia minore di zero, la quantità di nuovi ricoverati giornalieri è in aumento!
Vediamo ora invece quanti pazienti $S_t$ sono stati ricoverati in tutto da $t_0$ a $t$ e confrontiamolo col totale di tutti casi.
pS = []
for i, s in enumerate(S):
pS.append(s / totali[i])
fig = go.Figure(data=go.Scatter(
x=x, y=S,
mode='lines+markers',
marker_color="blue", marker_size=5, marker_symbol="circle", marker_line_width=1,
line={"dash": "dot"}, line_shape='spline',
name="ricoverati",
))
fig.add_trace(
go.Scatter(
x=x, y=totali,
mode='lines',
line={"dash": "dot"}, line_shape='spline',
name="totali"
)
)
fig.add_trace(
go.Scatter(
x=x, y=pS,
mode='lines',
line={"dash": "dot"}, line_shape='spline',
name="percentuale",
showlegend=False,
hovertemplate="%{y:.2%}"
)
)
fig.update_layout(legend_orientation="h",
showlegend=True, plot_bgcolor='rgba(0,0,0,0)',
yaxis={"gridcolor": '#bdbdbd', "zerolinecolor": '#969696'},
xaxis={"gridcolor": '#bdbdbd'},
title={"text": "ITALIA (totale cumulativo ricoverati)", "xanchor": "center", "x": 0.5},
yaxis_title="numero",
hovermode="x unified"
)
pyo.iplot(fig)
dunque la percentuale di ricoveri sul totale dei casi, all'11 di Aprile, è ancora superiore al 50%
Controlliamo ulteriormente la coerenza dei dati raccolti.
Se i pazienti in isolamento domiciliare sono conteggiati come casi ma non come guariti, la differenza tra il totale dei casi e il totale dei ricoveri dovrebbe essere uguale al totale dei pazienti in isolamento domiciliare.
for i, T in enumerate(totali):
print(x[i])
print("ISOLATI {} = TOTALI {} - RICOVERATI {}".format(
isolati[i], T, S[i]
))
if isolati[i] != (T - S[i]):
print("\033[41;37m ERR \033[0m")
else:
print("\033[42m OK! \033[0m")
print("---------------")
Dunque, attualmente nessuno dei pazienti in isolamento domiciliare è stato dichiarato guarito ma sono conteggiati come casi non guariti, non deceduti, aggiungendosi alla quantità di infetti.