Ahora que ya tenemos idea de cómo procesar los datos y conocemos más o menos su contenido, podemos empezar a hacer algunas visualizaciones. En general, el flujo de análisis de datos va y viene entre el preproceso, la visualización y el análisis. El tipo de preproceso va ligado a las visualizaciones que queremos hacer y estas van mostrando el camino del análisis, por lo tanto en la vida real uno siempre está yendo y viniendo entre estas etapas.
En este taller vamos a explorar gráficamente los datos y empezarnos a hacer preguntas sobre ellos, preguntas que intentaremos ir respondiendo con nuevas visualizaciones. Para ello vamos a partir de la base de datos que construimos en el taller anterior.
Como siempre, lo primero es importar las librerías que vamos a utlizar
import plotly.express as px
import pandas as pd
import seaborn as sns
from datetime import timedelta, date, datetime
Ahora sí podemos leer los datos.
df = pd.read_pickle("data/datos_covid_ene19.pkl")
df
FECHA_ACTUALIZACION | ID_REGISTRO | ORIGEN | SECTOR | ENTIDAD_UM | SEXO | ENTIDAD_NAC | ENTIDAD_RES | MUNICIPIO_RES | TIPO_PACIENTE | ... | TOMA_MUESTRA_ANTIGENO_BIN | MIGRANTE_BIN | UCI_BIN | DEFUNCION | AÑO_INGRESO | MES_INGRESO | DIA_SEMANA_INGRESO | SEMANA_AÑO_INGRESO | DIA_MES_INGRESO | DIA_AÑO_INGRESO | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
FECHA_INGRESO | |||||||||||||||||||||
2020-07-06 | 2022-01-18 | z12d63 | 2 | 12 | CIUDAD DE MÉXICO | 2 | CIUDAD DE MÉXICO | CIUDAD DE MÉXICO | VENUSTIANO CARRANZA | AMBULATORIO | ... | 0 | 0 | 0 | 0 | 2020 | 7 | 0 | 28 | 6 | 188 |
2020-09-23 | 2022-01-18 | z13788 | 1 | 12 | CIUDAD DE MÉXICO | 1 | CIUDAD DE MÉXICO | CIUDAD DE MÉXICO | CUAJIMALPA DE MORELOS | AMBULATORIO | ... | 0 | 0 | 0 | 0 | 2020 | 9 | 2 | 39 | 23 | 267 |
2020-06-15 | 2022-01-18 | z2b144 | 2 | 12 | CIUDAD DE MÉXICO | 1 | MÉXICO | CIUDAD DE MÉXICO | AZCAPOTZALCO | AMBULATORIO | ... | 0 | 0 | 0 | 0 | 2020 | 6 | 0 | 25 | 15 | 167 |
2020-12-21 | 2022-01-18 | z526b3 | 2 | 12 | CIUDAD DE MÉXICO | 1 | CIUDAD DE MÉXICO | CIUDAD DE MÉXICO | TLALPAN | AMBULATORIO | ... | 1 | 0 | 0 | 0 | 2020 | 12 | 0 | 52 | 21 | 356 |
2020-04-22 | 2022-01-18 | z3d1e2 | 2 | 12 | CIUDAD DE MÉXICO | 1 | CIUDAD DE MÉXICO | CIUDAD DE MÉXICO | GUSTAVO A. MADERO | AMBULATORIO | ... | 0 | 0 | 0 | 0 | 2020 | 4 | 2 | 17 | 22 | 113 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2021-10-11 | 2022-01-18 | m00073e | 2 | 12 | MÉXICO | 2 | NO ESPECIFICADO | CIUDAD DE MÉXICO | CUAUHTÉMOC | AMBULATORIO | ... | 1 | 0 | 0 | 0 | 2021 | 10 | 0 | 41 | 11 | 284 |
2021-10-13 | 2022-01-18 | m030623 | 2 | 12 | MÉXICO | 2 | MÉXICO | CIUDAD DE MÉXICO | TLÁHUAC | AMBULATORIO | ... | 1 | 0 | 0 | 0 | 2021 | 10 | 2 | 41 | 13 | 286 |
2021-10-13 | 2022-01-18 | m049633 | 2 | 12 | MÉXICO | 1 | CIUDAD DE MÉXICO | CIUDAD DE MÉXICO | GUSTAVO A. MADERO | AMBULATORIO | ... | 0 | 0 | 0 | 0 | 2021 | 10 | 2 | 41 | 13 | 286 |
2021-10-13 | 2022-01-18 | m160d02 | 2 | 12 | MÉXICO | 2 | CIUDAD DE MÉXICO | CIUDAD DE MÉXICO | GUSTAVO A. MADERO | AMBULATORIO | ... | 1 | 0 | 0 | 0 | 2021 | 10 | 2 | 41 | 13 | 286 |
2021-10-14 | 2022-01-18 | m0da9ec | 2 | 12 | MÉXICO | 1 | CIUDAD DE MÉXICO | CIUDAD DE MÉXICO | GUSTAVO A. MADERO | AMBULATORIO | ... | 1 | 0 | 0 | 0 | 2021 | 10 | 3 | 41 | 14 | 287 |
4279037 rows × 69 columns
Por lo pronto vamos a concentrarnos en la iodea de las Cuervas Epidémicas es decir, la evolución temporal de los casos confirmados y las defunciones. Si consultamos los diccionarios de datos, podemos ver que los casos confirmados para COVID-19 corresponden a 3 categorías de la columna clasificación final:
mientras que las defunciones corresponden a todos aquellos registros que tengan una fecha de defunción válida, es decir, en nuestros datos preprocesados, todas las fechas válidas.
df.CLASIFICACION_FINAL.unique()
array(['CASO SOSPECHOSO', 'CASO DE SARS-COV-2 CONFIRMADO', 'NO REALIZADO POR LABORATORIO', 'NEGATIVO A SARS-COV-2', 'CASO DE COVID-19 CONFIRMADO POR ASOCIACIÓN CLÍNICA EPIDEMIOLÓGICA', 'INVÁLIDO POR LABORATORIO', 'CASO DE COVID-19 CONFIRMADO POR COMITÉ DE DICTAMINACIÓN'], dtype=object)
valores_confirmados = ['CASO DE COVID-19 CONFIRMADO POR ASOCIACIÓN CLÍNICA EPIDEMIOLÓGICA',
'CASO DE COVID-19 CONFIRMADO POR COMITÉ DE DICTAMINACIÓN',
'CASO DE SARS-COV-2 CONFIRMADO']
confirmados = df.loc[df['CLASIFICACION_FINAL'].isin(valores_confirmados)]
confirmados.head()
FECHA_ACTUALIZACION | ID_REGISTRO | ORIGEN | SECTOR | ENTIDAD_UM | SEXO | ENTIDAD_NAC | ENTIDAD_RES | MUNICIPIO_RES | TIPO_PACIENTE | ... | TOMA_MUESTRA_ANTIGENO_BIN | MIGRANTE_BIN | UCI_BIN | DEFUNCION | AÑO_INGRESO | MES_INGRESO | DIA_SEMANA_INGRESO | SEMANA_AÑO_INGRESO | DIA_MES_INGRESO | DIA_AÑO_INGRESO | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
FECHA_INGRESO | |||||||||||||||||||||
2020-09-23 | 2022-01-18 | z13788 | 1 | 12 | CIUDAD DE MÉXICO | 1 | CIUDAD DE MÉXICO | CIUDAD DE MÉXICO | CUAJIMALPA DE MORELOS | AMBULATORIO | ... | 0 | 0 | 0 | 0 | 2020 | 9 | 2 | 39 | 23 | 267 |
2020-12-21 | 2022-01-18 | z526b3 | 2 | 12 | CIUDAD DE MÉXICO | 1 | CIUDAD DE MÉXICO | CIUDAD DE MÉXICO | TLALPAN | AMBULATORIO | ... | 1 | 0 | 0 | 0 | 2020 | 12 | 0 | 52 | 21 | 356 |
2020-04-22 | 2022-01-18 | z3d1e2 | 2 | 12 | CIUDAD DE MÉXICO | 1 | CIUDAD DE MÉXICO | CIUDAD DE MÉXICO | GUSTAVO A. MADERO | AMBULATORIO | ... | 0 | 0 | 0 | 0 | 2020 | 4 | 2 | 17 | 22 | 113 |
2020-10-07 | 2022-01-18 | zz9079 | 2 | 12 | CIUDAD DE MÉXICO | 1 | CIUDAD DE MÉXICO | CIUDAD DE MÉXICO | IZTAPALAPA | AMBULATORIO | ... | 0 | 0 | 0 | 0 | 2020 | 10 | 2 | 41 | 7 | 281 |
2020-09-08 | 2022-01-18 | z2770b | 1 | 12 | CIUDAD DE MÉXICO | 1 | CIUDAD DE MÉXICO | CIUDAD DE MÉXICO | IZTACALCO | AMBULATORIO | ... | 0 | 0 | 0 | 0 | 2020 | 9 | 1 | 37 | 8 | 252 |
5 rows × 69 columns
Ahora tenemos una tabla con todos los casos confirmados, para hacer una curva epidémica, tenemos que agregar en una escala temporal. Lo más sencillo es primero agragar por día y a partir de ahí podemos construir agregados para cualquier intervalo que queramos.
Para poder construir las curvas epidémicas necesitamos decidir cuáál fecha de todas las disponibles vamos a utilizar para agregar los casos. En este caso, la DGE sugiere utilizar la fecha de inicio de síntomas (FECHA_SINTOMAS
) para construir la curva de casos confirmados y la de defunción (FECHA_DEF
) para la curva de defunciones.
Entonces, para construir la curva de confirmados lo primero que tenemos que hacer es indexar el DataFrame por la fecha de inicio de síntomas
confirmados = confirmados.set_index('FECHA_SINTOMAS')
confirmados.index
DatetimeIndex(['2020-09-23', '2020-12-18', '2020-04-20', '2020-10-06', '2020-09-03', '2020-10-16', '2020-12-22', '2020-03-03', '2020-03-03', '2020-03-03', ... '2021-09-07', '2021-09-02', '2021-09-21', '2021-09-28', '2021-10-06', '2021-10-01', '2021-10-02', '2021-10-03', '2021-10-03', '2021-10-03'], dtype='datetime64[ns]', name='FECHA_SINTOMAS', length=1109842, freq=None)
Entonces es fácil construir agregados diarios, sólo tenemos que seleccionar qué columnas queremos agregar. Por lo pronto hagamos un conteo sólo de casos confirmados. Para eso sólo tenemos que agrupár el ídice usando una frecuencia diaría y tomar el tamaño de los grupos (de alguna columna, realmente no importa cual).
confirmados_diarios = (confirmados
.groupby(pd.Grouper(freq='D'))[['ID_REGISTRO']] # grupos por dia y seleccionamos 'ID_REGISTRO'
.size() # Calculamos el tamaño de cada grupo
.reset_index() # Convertimos el resultado (que es una serie) en DataFrame
.rename({0:'Confirmados'}, axis=1) # Le damos nombre a la columna que obtenemos
)
confirmados_diarios
FECHA_SINTOMAS | Confirmados | |
---|---|---|
0 | 2020-02-22 | 1 |
1 | 2020-02-23 | 1 |
2 | 2020-02-24 | 0 |
3 | 2020-02-25 | 0 |
4 | 2020-02-26 | 0 |
... | ... | ... |
691 | 2022-01-13 | 3829 |
692 | 2022-01-14 | 3068 |
693 | 2022-01-15 | 1860 |
694 | 2022-01-16 | 665 |
695 | 2022-01-17 | 1029 |
696 rows × 2 columns
Con estos datos podemos usar Plotly para hacer una gráfica interactiva de forma muy sencilla.
fig = px.line(confirmados_diarios, x='FECHA_SINTOMAS', y="Confirmados")
fig.show()