En esta práctica vamos a utilizar "Pandas", la librería de Phyton, para trabajar sobre los datos de la Covid-19 y analizarlos.
Para instalar la librería utilizaremos la función "!pip". La exclamación es necesaria porque no estamos ejecutando Python, sino bash.
!pip install pandas
Requirement already satisfied: pandas in /usr/local/lib/python3.8/dist-packages (1.3.1) Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.8/dist-packages (from pandas) (2020.4) Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.8/dist-packages (from pandas) (2.8.1) Requirement already satisfied: numpy>=1.17.3 in /usr/local/lib/python3.8/dist-packages (from pandas) (1.21.1) Requirement already satisfied: six>=1.5 in /usr/lib/python3/dist-packages (from python-dateutil>=2.7.3->pandas) (1.14.0)
Para importar utilizaremos la convención "pd" como abrebiatura para llamar a la librería.
import pandas as pd
Las variables se asignan con el símbolo "=" y los escribimos entrecomillados por ser una cadena de caracteres.
url = "https://api.covid19api.com/countries"
La abreviatura que se emplea para los dataframe es "df". Existe una función "read_json()" que lo que hace es leer el formato "json". Dentro del paréntesis indicaremos el valor de lo que queremos que lea, en este caso la url.
df = pd.read_json(url)
Para visualizar los datos llamamos al objeto. Observaremos una tabla que contiene tres columnas y una columna de control de Pandas, que identifica cada una de las entradas del dataframe.
df
| Country | Slug | ISO2 | |
|---|---|---|---|
| 0 | Gambia | gambia | GM |
| 1 | Paraguay | paraguay | PY |
| 2 | Trinidad and Tobago | trinidad-and-tobago | TT |
| 3 | Austria | austria | AT |
| 4 | Sao Tome and Principe | sao-tome-and-principe | ST |
| ... | ... | ... | ... |
| 243 | Cape Verde | cape-verde | CV |
| 244 | Israel | israel | IL |
| 245 | Bolivia | bolivia | BO |
| 246 | Latvia | latvia | LV |
| 247 | Papua New Guinea | papua-new-guinea | PG |
248 rows × 3 columns
Para ver las primeras entradas de la tabla utilizaremos la siguiente función. Como metemos el número 6 veremos las seis primeras observaciones.
df.head(6)
| Country | Slug | ISO2 | |
|---|---|---|---|
| 0 | Gambia | gambia | GM |
| 1 | Paraguay | paraguay | PY |
| 2 | Trinidad and Tobago | trinidad-and-tobago | TT |
| 3 | Austria | austria | AT |
| 4 | Sao Tome and Principe | sao-tome-and-principe | ST |
| 5 | Timor-Leste | timor-leste | TL |
Para ver las 6 últimas entradas:
df.tail(6)
| Country | Slug | ISO2 | |
|---|---|---|---|
| 242 | Barbados | barbados | BB |
| 243 | Cape Verde | cape-verde | CV |
| 244 | Israel | israel | IL |
| 245 | Bolivia | bolivia | BO |
| 246 | Latvia | latvia | LV |
| 247 | Papua New Guinea | papua-new-guinea | PG |
Para ver las información sobre las variables que contiene el dataframe utilizamos la siguiente función:
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 248 entries, 0 to 247 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Country 248 non-null object 1 Slug 248 non-null object 2 ISO2 248 non-null object dtypes: object(3) memory usage: 5.9+ KB
Para visualizar solo una de las variables:
df['Country']
0 Gambia
1 Paraguay
2 Trinidad and Tobago
3 Austria
4 Sao Tome and Principe
...
243 Cape Verde
244 Israel
245 Bolivia
246 Latvia
247 Papua New Guinea
Name: Country, Length: 248, dtype: object
Para ver un valor concreto de una de las variables:
df['Country'][66]
'Honduras'
La URL que utilizaremos ahora es la siguiente: https://api.covid19.api.com/country/spain/status/confirmed/live
Guardaremos los datos de la misma manera que lo hicimos anteriormente, pero añadiendo "df_es" (abreviatura de España) para identificar que este dataframe es de este país concreto.
url_es = 'https://api.covid19api.com/country/spain/status/confirmed/live'
df_es = pd.read_json(url_es)
df_es
| Country | CountryCode | Province | City | CityCode | Lat | Lon | Cases | Status | Date | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Spain | ES | 40.46 | -3.75 | 0 | confirmed | 2020-01-22 00:00:00+00:00 | |||
| 1 | Spain | ES | 40.46 | -3.75 | 0 | confirmed | 2020-01-23 00:00:00+00:00 | |||
| 2 | Spain | ES | 40.46 | -3.75 | 0 | confirmed | 2020-01-24 00:00:00+00:00 | |||
| 3 | Spain | ES | 40.46 | -3.75 | 0 | confirmed | 2020-01-25 00:00:00+00:00 | |||
| 4 | Spain | ES | 40.46 | -3.75 | 0 | confirmed | 2020-01-26 00:00:00+00:00 | |||
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 816 | Spain | ES | 40.46 | -3.75 | 11662214 | confirmed | 2022-04-17 00:00:00+00:00 | |||
| 817 | Spain | ES | 40.46 | -3.75 | 11662214 | confirmed | 2022-04-18 00:00:00+00:00 | |||
| 818 | Spain | ES | 40.46 | -3.75 | 11736893 | confirmed | 2022-04-19 00:00:00+00:00 | |||
| 819 | Spain | ES | 40.46 | -3.75 | 11736893 | confirmed | 2022-04-20 00:00:00+00:00 | |||
| 820 | Spain | ES | 40.46 | -3.75 | 11736893 | confirmed | 2022-04-21 00:00:00+00:00 |
821 rows × 10 columns
Por columnas:
df_es.columns
Index(['Country', 'CountryCode', 'Province', 'City', 'CityCode', 'Lat', 'Lon',
'Cases', 'Status', 'Date'],
dtype='object')
Cabecera
df_es.head(2)
| Country | CountryCode | Province | City | CityCode | Lat | Lon | Cases | Status | Date | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Spain | ES | 40.46 | -3.75 | 0 | confirmed | 2020-01-22 00:00:00+00:00 | |||
| 1 | Spain | ES | 40.46 | -3.75 | 0 | confirmed | 2020-01-23 00:00:00+00:00 |
Cola
df_es.tail(2)
| Country | CountryCode | Province | City | CityCode | Lat | Lon | Cases | Status | Date | |
|---|---|---|---|---|---|---|---|---|---|---|
| 819 | Spain | ES | 40.46 | -3.75 | 11736893 | confirmed | 2022-04-20 00:00:00+00:00 | |||
| 820 | Spain | ES | 40.46 | -3.75 | 11736893 | confirmed | 2022-04-21 00:00:00+00:00 |
Información sobre las variables
df_es.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 821 entries, 0 to 820 Data columns (total 10 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Country 821 non-null object 1 CountryCode 821 non-null object 2 Province 821 non-null object 3 City 821 non-null object 4 CityCode 821 non-null object 5 Lat 821 non-null float64 6 Lon 821 non-null float64 7 Cases 821 non-null int64 8 Status 821 non-null object 9 Date 821 non-null datetime64[ns, UTC] dtypes: datetime64[ns, UTC](1), float64(2), int64(1), object(6) memory usage: 64.3+ KB
Para obtener una descripción estadística de las variables numéricas del dataframe (obtenemos el número total, la media, la desviación, el mínimo y máximo y los cuartiles):
df_es.describe()
| Lat | Lon | Cases | |
|---|---|---|---|
| count | 8.210000e+02 | 821.00 | 8.210000e+02 |
| mean | 4.046000e+01 | -3.75 | 3.426515e+06 |
| std | 1.421952e-14 | 0.00 | 3.312558e+06 |
| min | 4.046000e+01 | -3.75 | 0.000000e+00 |
| 25% | 4.046000e+01 | -3.75 | 3.428130e+05 |
| 50% | 4.046000e+01 | -3.75 | 3.180212e+06 |
| 75% | 4.046000e+01 | -3.75 | 4.953930e+06 |
| max | 4.046000e+01 | -3.75 | 1.173689e+07 |
Para elaborar el gráfico en el eje X la fecha y en el eje Y los casos confirmados.
Para ello vamos a establecer la fecha como índice de la función. Esto hace que nuestras entradas se identifiquen por la fecha y no por el índice que le había dado Pandas en un inicio.
df_es.set_index('Date')
| Country | CountryCode | Province | City | CityCode | Lat | Lon | Cases | Status | |
|---|---|---|---|---|---|---|---|---|---|
| Date | |||||||||
| 2020-01-22 00:00:00+00:00 | Spain | ES | 40.46 | -3.75 | 0 | confirmed | |||
| 2020-01-23 00:00:00+00:00 | Spain | ES | 40.46 | -3.75 | 0 | confirmed | |||
| 2020-01-24 00:00:00+00:00 | Spain | ES | 40.46 | -3.75 | 0 | confirmed | |||
| 2020-01-25 00:00:00+00:00 | Spain | ES | 40.46 | -3.75 | 0 | confirmed | |||
| 2020-01-26 00:00:00+00:00 | Spain | ES | 40.46 | -3.75 | 0 | confirmed | |||
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2022-04-17 00:00:00+00:00 | Spain | ES | 40.46 | -3.75 | 11662214 | confirmed | |||
| 2022-04-18 00:00:00+00:00 | Spain | ES | 40.46 | -3.75 | 11662214 | confirmed | |||
| 2022-04-19 00:00:00+00:00 | Spain | ES | 40.46 | -3.75 | 11736893 | confirmed | |||
| 2022-04-20 00:00:00+00:00 | Spain | ES | 40.46 | -3.75 | 11736893 | confirmed | |||
| 2022-04-21 00:00:00+00:00 | Spain | ES | 40.46 | -3.75 | 11736893 | confirmed |
821 rows × 9 columns
Como necesito una tabla que también refleje los casos confirmados crearemos una vista en la que ver el número de casos confirmados por fecha.
df_es.set_index('Date')['Cases']
Date
2020-01-22 00:00:00+00:00 0
2020-01-23 00:00:00+00:00 0
2020-01-24 00:00:00+00:00 0
2020-01-25 00:00:00+00:00 0
2020-01-26 00:00:00+00:00 0
...
2022-04-17 00:00:00+00:00 11662214
2022-04-18 00:00:00+00:00 11662214
2022-04-19 00:00:00+00:00 11736893
2022-04-20 00:00:00+00:00 11736893
2022-04-21 00:00:00+00:00 11736893
Name: Cases, Length: 821, dtype: int64
Sobre este vista creamos el gráfico a través de la función "plot".
df_es.set_index('Date')['Cases'].plot()
<AxesSubplot:xlabel='Date'>
Nombraremos nuestro gráfico con el atributo title:
df_es.set_index('Date')['Cases'].plot(title= "Casos de Covid19 en España")
<AxesSubplot:title={'center':'Casos de Covid19 en España'}, xlabel='Date'>
Repetimos la operación con un nuevo país, Italia. Lo identificamos con _it
url_it = 'https://api.covid19api.com/country/italy/status/confirmed/live'
df_it = pd.read_json(url_it)
df_it.set_index('Date')['Cases'].plot(title= "Casos de Covid19 Italia")
<AxesSubplot:title={'center':'Casos de Covid19 Italia'}, xlabel='Date'>
Ahora con Uruguay (_ur):
url_ur = 'https://api.covid19api.com/country/uruguay/status/confirmed/live'
df_ur = pd.read_json(url_ur)
df_ur.set_index('Date')['Cases'].plot(title= "Casos de Covid19 Uruguay")
<AxesSubplot:title={'center':'Casos de Covid19 Uruguay'}, xlabel='Date'>
Las vistas creadas antes las vamos a guardar como objetos para poder agruparlos y compararlos.
casos_es = df_es.set_index('Date')['Cases']
casos_it = df_it.set_index('Date')['Cases']
casos_ur = df_ur.set_index('Date')['Cases']
casos_ur
Date
2020-01-22 00:00:00+00:00 0
2020-01-23 00:00:00+00:00 0
2020-01-24 00:00:00+00:00 0
2020-01-25 00:00:00+00:00 0
2020-01-26 00:00:00+00:00 0
...
2022-04-18 00:00:00+00:00 895775
2022-04-19 00:00:00+00:00 895775
2022-04-20 00:00:00+00:00 895775
2022-04-21 00:00:00+00:00 895775
2022-04-22 00:00:00+00:00 895775
Name: Cases, Length: 822, dtype: int64
Vamos a concatenar los daots con la función pd.concat. Así los uniremos en el mismo dataframe. Es importante hacer la concatenación en el eje 1 (axis=1)
pd.concat([casos_es,casos_it,casos_ur],axis=1)
| Cases | Cases | Cases | |
|---|---|---|---|
| Date | |||
| 2020-01-22 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| 2020-01-23 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| 2020-01-24 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| 2020-01-25 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| 2020-01-26 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| ... | ... | ... | ... |
| 2022-04-18 00:00:00+00:00 | 11662214.0 | 15730676.0 | 895775 |
| 2022-04-19 00:00:00+00:00 | 11736893.0 | 15758002.0 | 895775 |
| 2022-04-20 00:00:00+00:00 | 11736893.0 | 15858442.0 | 895775 |
| 2022-04-21 00:00:00+00:00 | 11736893.0 | 15934437.0 | 895775 |
| 2022-04-22 00:00:00+00:00 | NaN | NaN | 895775 |
822 rows × 3 columns
Para comparar los datos de los países vamos a crear un objeto llamado "vs".
vs = pd.concat([casos_es,casos_it,casos_ur],axis=1)
vs
| Cases | Cases | Cases | |
|---|---|---|---|
| Date | |||
| 2020-01-22 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| 2020-01-23 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| 2020-01-24 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| 2020-01-25 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| 2020-01-26 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| ... | ... | ... | ... |
| 2022-04-18 00:00:00+00:00 | 11662214.0 | 15730676.0 | 895775 |
| 2022-04-19 00:00:00+00:00 | 11736893.0 | 15758002.0 | 895775 |
| 2022-04-20 00:00:00+00:00 | 11736893.0 | 15858442.0 | 895775 |
| 2022-04-21 00:00:00+00:00 | 11736893.0 | 15934437.0 | 895775 |
| 2022-04-22 00:00:00+00:00 | NaN | NaN | 895775 |
822 rows × 3 columns
Ahora crearemos el gráfico. Para ello vamos a nombrar las variables, los casos de cada país, con el nombre del país para la leyenda del gráfico:
vs.columns = ['España', 'Italia', 'Uruguay']
vs
| España | Italia | Uruguay | |
|---|---|---|---|
| Date | |||
| 2020-01-22 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| 2020-01-23 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| 2020-01-24 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| 2020-01-25 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| 2020-01-26 00:00:00+00:00 | 0.0 | 0.0 | 0 |
| ... | ... | ... | ... |
| 2022-04-18 00:00:00+00:00 | 11662214.0 | 15730676.0 | 895775 |
| 2022-04-19 00:00:00+00:00 | 11736893.0 | 15758002.0 | 895775 |
| 2022-04-20 00:00:00+00:00 | 11736893.0 | 15858442.0 | 895775 |
| 2022-04-21 00:00:00+00:00 | 11736893.0 | 15934437.0 | 895775 |
| 2022-04-22 00:00:00+00:00 | NaN | NaN | 895775 |
822 rows × 3 columns
Como antes para visualizar el gráfico utilizaremos la función "plot":
vs.plot(title="España vs Italia vs Uruguay")
<AxesSubplot:title={'center':'España vs Italia vs Uruguay'}, xlabel='Date'>
Vamos a elegir el tipo que gráfico que queremos, un gráfico de áreas, con el atributo "kind"
vs.plot(title="España vs Italia vs Uruguay", kind='area')
<AxesSubplot:title={'center':'España vs Italia vs Uruguay'}, xlabel='Date'>
Vamos a guardar el dataframe "vs" como csv de la siguiente manera:
vs.to_csv('esvsit.csv')
Para ver dónde lo hemos guardado:
!ls
api-pandas-folium.ipynb probando-con-r.ipynb Shared_Resources esvsit.csv python-api-covid-pandas.ipynb Untitled.ipynb
Importamos la librería matplotlib para guardarlo porque es aquella que permite visualizar los datos en Python.
import matplotlib.pyplot as plt
vs.plot()
plt.savefig('esvsit.png')