pandas: biblioteca para análisis y manipulación de datos#

Abrir en Colab

Introducción#

pandas es una biblioteca de Python para análisis y manipulación de datos. Fue creada por Wes McKinney en 2008. El nombre “pandas” puede considerarse un acrónimo de Panel Data o de Python Data Analysis.

Como su estructura principal, pandas implementa el dataframe, el cual es un arreglo rectangular de datos, organizado en filas y columnas. pandas proporciona también una gran cantidad de funciones para limpiar, procesar, analizar y visualizar datos en dataframes.

Carga#

# Carga de pandas con el alias pd
import pandas as pd

Configuración#

El método pandas.set_option() se utiliza para configurar diversas opciones que controlan el comportamiento de pandas y la visualización de datos. Estas opciones permiten personalizar aspectos como:

  • El número de filas y columnas que se muestran al desplegar conjuntos de datos.

  • La precisión al mostrar números decimales.

  • El ancho máximo de filas y columnas.

  • El formato de la fecha y la hora.

# Configuración de pandas para mostrar separadores de miles y 2 dígitos decimales
# Esto también evita la notación científica

pd.set_option('display.float_format', '{:,.2f}'.format)

Otras funciones relacionadas con la configuración de pandas:

  • pandas.describe_option(): muestra información sobre una opción (ej. pd.describe_option('display.max_rows')). pd.describe_option() describe todas las opciones.

  • pandas.get_option(): muestra el valor actual de una opción de configuración (ej. pd.get_option('display.max_rows')).

  • pandas.reset_option(): reestablece el valor por defecto de una opción de configuración (ej. pd.reset_option('display.max_rows')). pd.reset_option('all') reestablece todas las opciones.

Debe tenerse en cuenta que el uso de estas funciones aplica para toda una sesión de pandas y no, por ejemplo, para conjuntos de datos específicos.

Estructuras de datos#

Las dos principales estructuras de datos de pandas son las series y los dataframes.

Series#

Las series son arreglos unidimensionales que contienen datos de cualquier tipo.

# Definición de una serie a partir de una lista

lista_primos = [2, 3, 5, 7, 11]
serie_primos = pd.Series(lista_primos)

print(serie_primos)
0     2
1     3
2     5
3     7
4    11
dtype: int64

Al igual que otras estructuras de datos de Python (ej. tuplas, listas), cada elemento de una serie tiene un índice (i.e. una posición). El índice del primer elemento es 0, el del segundo elemento es 1 y así sucesivamente.

# Primer elemento
print("Primer elemento:", serie_primos[0])

# Segundo elemento
print("Segundo elemento:", serie_primos[1])
Primer elemento: 2
Segundo elemento: 3

A diferencia de las tuplas y las listas, las series pueden tener índices no numéricos, a los cuales se les llama etiquetas.

# Índices de una serie con etiquetas personalizadas
serie_primos = pd.Series(lista_primos, index = ["A", "B", "C", "D", "E"])

serie_primos
A     2
B     3
C     5
D     7
E    11
dtype: int64
# Elemento en la posición B
print("Elemento en B:", serie_primos["B"])

# Elemento en la posición D
print("Elemento en D:", serie_primos["D"])
Elemento en B: 3
Elemento en D: 7

Ejercicios

  1. Cree una serie que contenga los montos de ventas de una tienda para los 12 meses del año. Utilice los nombres de los meses como índices.

Dataframes#

Los dataframes son estructuras de datos multidimensionales compuestas por filas y columnas. Un dataframe puede verse como una tabla cuyas columnas se implementan como series.

# Dataframe generado a partir de un diccionario

diccionario_paises = {
  "pais": ["PA", "CR", "NI"],
  "poblacion": [4246439, 5047561, 6545502]
}

df_paises = pd.DataFrame(diccionario_paises)

df_paises
pais poblacion
0 PA 4246439
1 CR 5047561
2 NI 6545502

La propiedad iloc retorna una o más filas de un dataframe, de acuerdo con un índice o una lista de índices.

# Segunda fila
df_paises.iloc[1]
pais              CR
poblacion    5047561
Name: 1, dtype: object
# Segunda y tercera fila
df_paises.loc[[1, 2]]
pais poblacion
1 CR 5047561
2 NI 6545502

Los índices de los dataframes también pueden etiquetarse.

# Dataframe con índices etiquetados

df_paises = pd.DataFrame(diccionario_paises, index=["pais_0", "pais_1", "pais_2"])

df_paises
pais poblacion
pais_0 PA 4246439
pais_1 CR 5047561
pais_2 NI 6545502

La propiedad loc retorna una o más filas de un dataframe, de acuerdo con sus etiquetas.

# Fila en "pais_0"
df_paises.loc["pais_0"]
pais              PA
poblacion    4246439
Name: pais_0, dtype: object

Operaciones básicas#

Seguidamente, se describen y ejemplifican algunas de las funciones básicas que pueden realizarse en un dataframe de pandas.

En los siguientes ejemplos, se utilizará un conjunto de datos de países descargado de Natural Earth.

Carga de datos#

El método pandas.read_csv() carga un archivo de valores separados por comas (CSV) en un dataframe.

# Carga de un archivo CSV remoto en un dataframe

paises = pd.read_csv(
    "https://raw.githubusercontent.com/gf0657-programacionsig/2024-ii/refs/heads/main/datos/natural-earth/paises.csv"
)

Ejercicios

  1. Descargue en su computadora el archivo paises.csv y cárguelo en otro dataframe.

Obtención de información general#

El método pandas.DataFrame.info() despliega un resumen de información sobre un dataframe.

# Información general sobre un dataframe

paises.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 201 entries, 0 to 200
Data columns (total 10 columns):
 #   Column      Non-Null Count  Dtype  
---  ------      --------------  -----  
 0   ADM0_ISO    201 non-null    object 
 1   NAME        201 non-null    object 
 2   CONTINENT   201 non-null    object 
 3   REGION_UN   201 non-null    object 
 4   SUBREGION   201 non-null    object 
 5   REGION_WB   201 non-null    object 
 6   ECONOMY     201 non-null    object 
 7   INCOME_GRP  201 non-null    object 
 8   POP_EST     201 non-null    float64
 9   GDP_MD      201 non-null    int64  
dtypes: float64(1), int64(1), object(8)
memory usage: 15.8+ KB

Funciones básicas de recuperación y despliegue de datos#

Los datos contenidos en un dataframe pueden visualizarse con la función print(). En un cuaderno de notas, basta también con ejecutar una celda con el nombre del dataframe. Esta última opción genera una salida más legible.

# Despliegue de los datos de un dataframe

paises
ADM0_ISO NAME CONTINENT REGION_UN SUBREGION REGION_WB ECONOMY INCOME_GRP POP_EST GDP_MD
0 IDN Indonesia Asia Asia South-Eastern Asia East Asia & Pacific 4. Emerging region: MIKT 4. Lower middle income 270,625,568.00 1119190
1 MYS Malaysia Asia Asia South-Eastern Asia East Asia & Pacific 6. Developing region 3. Upper middle income 31,949,777.00 364681
2 CHL Chile South America Americas South America Latin America & Caribbean 5. Emerging region: G20 3. Upper middle income 18,952,038.00 282318
3 BOL Bolivia South America Americas South America Latin America & Caribbean 5. Emerging region: G20 4. Lower middle income 11,513,100.00 40895
4 PER Peru South America Americas South America Latin America & Caribbean 5. Emerging region: G20 3. Upper middle income 32,510,453.00 226848
... ... ... ... ... ... ... ... ... ... ...
196 NRU Nauru Oceania Oceania Micronesia East Asia & Pacific 6. Developing region 4. Lower middle income 12,581.00 118
197 FSM Micronesia Oceania Oceania Micronesia East Asia & Pacific 6. Developing region 4. Lower middle income 113,815.00 401
198 VUT Vanuatu Oceania Oceania Melanesia East Asia & Pacific 7. Least developed region 4. Lower middle income 299,882.00 934
199 PLW Palau Oceania Oceania Micronesia East Asia & Pacific 6. Developing region 3. Upper middle income 18,008.00 268
200 BHR Bahrain Asia Asia Western Asia Middle East & North Africa 6. Developing region 2. High income: nonOECD 1,641,172.00 38574

201 rows × 10 columns

Es posible que la cantidad de filas sea muy grande para desplegarse completamente en la pantalla, por lo que es usual emplear algunos métodos para limitarla.

head() - primeras filas#

El método pandas.DataFrame.head() retorna las primeras n filas de un dataframe (por defecto, n=5).

# Primeras 5 filas de un dataframe

paises.head()
ADM0_ISO NAME CONTINENT REGION_UN SUBREGION REGION_WB ECONOMY INCOME_GRP POP_EST GDP_MD
0 IDN Indonesia Asia Asia South-Eastern Asia East Asia & Pacific 4. Emerging region: MIKT 4. Lower middle income 270,625,568.00 1119190
1 MYS Malaysia Asia Asia South-Eastern Asia East Asia & Pacific 6. Developing region 3. Upper middle income 31,949,777.00 364681
2 CHL Chile South America Americas South America Latin America & Caribbean 5. Emerging region: G20 3. Upper middle income 18,952,038.00 282318
3 BOL Bolivia South America Americas South America Latin America & Caribbean 5. Emerging region: G20 4. Lower middle income 11,513,100.00 40895
4 PER Peru South America Americas South America Latin America & Caribbean 5. Emerging region: G20 3. Upper middle income 32,510,453.00 226848

tail() - últimas filas#

El método pandas.DataFrame.tail() retorna las últimas n filas de un dataframe (por defecto, n=5).

# Últimas 10 filas de un dataframe

paises.tail(10)
ADM0_ISO NAME CONTINENT REGION_UN SUBREGION REGION_WB ECONOMY INCOME_GRP POP_EST GDP_MD
191 TON Tonga Oceania Oceania Polynesia East Asia & Pacific 6. Developing region 4. Lower middle income 104,494.00 512
192 WSM Samoa Oceania Oceania Polynesia East Asia & Pacific 7. Least developed region 4. Lower middle income 197,097.00 852
193 SLB Solomon Is. Oceania Oceania Melanesia East Asia & Pacific 7. Least developed region 4. Lower middle income 669,823.00 1589
194 TUV Tuvalu Oceania Oceania Polynesia East Asia & Pacific 7. Least developed region 3. Upper middle income 11,646.00 47
195 MDV Maldives Seven seas (open ocean) Asia Southern Asia South Asia 6. Developing region 3. Upper middle income 530,953.00 5642
196 NRU Nauru Oceania Oceania Micronesia East Asia & Pacific 6. Developing region 4. Lower middle income 12,581.00 118
197 FSM Micronesia Oceania Oceania Micronesia East Asia & Pacific 6. Developing region 4. Lower middle income 113,815.00 401
198 VUT Vanuatu Oceania Oceania Melanesia East Asia & Pacific 7. Least developed region 4. Lower middle income 299,882.00 934
199 PLW Palau Oceania Oceania Micronesia East Asia & Pacific 6. Developing region 3. Upper middle income 18,008.00 268
200 BHR Bahrain Asia Asia Western Asia Middle East & North Africa 6. Developing region 2. High income: nonOECD 1,641,172.00 38574

sample() - muestra aleatoria de filas#

El método pandas.DataFrame.sample() retorna una muestra aleatoria de n filas de un dataframe (por defecto, n=1).

# Muestra aleatoria de 3 filas de un dataframe

paises.sample(3)
ADM0_ISO NAME CONTINENT REGION_UN SUBREGION REGION_WB ECONOMY INCOME_GRP POP_EST GDP_MD
104 PAK Pakistan Asia Asia Southern Asia South Asia 5. Emerging region: G20 4. Lower middle income 216,565,318.00 278221
161 CYP Cyprus U.N. Buffer Zone Asia Asia Western Asia Europe & Central Asia 6. Developing region 2. High income: nonOECD 10,000.00 280
62 SRB Kosovo Europe Europe Southern Europe Europe & Central Asia 6. Developing region 4. Lower middle income 1,794,248.00 7926

Creación de subconjuntos#

Una de las operaciones más comunes de manipulación y análisis de datos es la creación de subconjuntos. En el caso de un dataframe, estos subconjuntos pueden ser de filas, de columnas o de ambas a la vez. Pueden crearse de varias formas.

Mediante índices numéricos#

La propiedad pandas.DataFrame.iloc permite seleccionar filas y columnas de un dataframe por sus índices numéricos.

Índice de una fila:

# Fila 0
paises.iloc[0]
ADM0_ISO                           IDN
NAME                         Indonesia
CONTINENT                         Asia
REGION_UN                         Asia
SUBREGION           South-Eastern Asia
REGION_WB          East Asia & Pacific
ECONOMY       4. Emerging region: MIKT
INCOME_GRP      4. Lower middle income
POP_EST                 270,625,568.00
GDP_MD                         1119190
Name: 0, dtype: object

Rango de filas:

# Filas entre la 5 (inclusive) y la 7 (inclusive)
paises.iloc[5:8]
ADM0_ISO NAME CONTINENT REGION_UN SUBREGION REGION_WB ECONOMY INCOME_GRP POP_EST GDP_MD
5 ARG Argentina South America Americas South America Latin America & Caribbean 5. Emerging region: G20 3. Upper middle income 44,938,712.00 445445
6 GBR United Kingdom Europe Europe Northern Europe Europe & Central Asia 1. Developed region: G7 1. High income: OECD 67,366,465.00 2863166
7 CYP Cyprus Asia Asia Western Asia Europe & Central Asia 6. Developing region 2. High income: nonOECD 1,198,575.00 24948

Lista de índices de filas:

# Filas 3, 5 y 7
paises.iloc[[3, 5, 7]]
ADM0_ISO NAME CONTINENT REGION_UN SUBREGION REGION_WB ECONOMY INCOME_GRP POP_EST GDP_MD
3 BOL Bolivia South America Americas South America Latin America & Caribbean 5. Emerging region: G20 4. Lower middle income 11,513,100.00 40895
5 ARG Argentina South America Americas South America Latin America & Caribbean 5. Emerging region: G20 3. Upper middle income 44,938,712.00 445445
7 CYP Cyprus Asia Asia Western Asia Europe & Central Asia 6. Developing region 2. High income: nonOECD 1,198,575.00 24948

Mediante etiquetas#

La propiedad pandas.DataFrame.loc permite seleccionar filas y columnas de un dataframe por sus etiquetas.

El método pandas.DataFrame.set_index() crea índices (etiquetas en las filas) para un dataframe con base en columnas existentes.

# Se usa la columna ADM0_ISO como índice
paises.set_index('ADM0_ISO', inplace=True)

paises.iloc[0:5]
NAME CONTINENT REGION_UN SUBREGION REGION_WB ECONOMY INCOME_GRP POP_EST GDP_MD
ADM0_ISO
IDN Indonesia Asia Asia South-Eastern Asia East Asia & Pacific 4. Emerging region: MIKT 4. Lower middle income 270,625,568.00 1119190
MYS Malaysia Asia Asia South-Eastern Asia East Asia & Pacific 6. Developing region 3. Upper middle income 31,949,777.00 364681
CHL Chile South America Americas South America Latin America & Caribbean 5. Emerging region: G20 3. Upper middle income 18,952,038.00 282318
BOL Bolivia South America Americas South America Latin America & Caribbean 5. Emerging region: G20 4. Lower middle income 11,513,100.00 40895
PER Peru South America Americas South America Latin America & Caribbean 5. Emerging region: G20 3. Upper middle income 32,510,453.00 226848

Si se desea reestablecer el índice al numérico predeterminado, puede utilizarse el método pandas.DataFrame.reset_index().

Una vez que se han creado las etiquetas, puede usarse loc para seleccionarlas.

# Fila correspondiente a Costa Rica
paises.loc['CRI']
NAME                         Costa Rica
CONTINENT                 North America
REGION_UN                      Americas
SUBREGION               Central America
REGION_WB     Latin America & Caribbean
ECONOMY         5. Emerging region: G20
INCOME_GRP       3. Upper middle income
POP_EST                    5,047,561.00
GDP_MD                            61801
Name: CRI, dtype: object
# Lista de filas correspondientes a Costa Rica, Nicaragua y Panamá
paises.loc[['CRI', 'NIC', 'PAN']]
NAME CONTINENT REGION_UN SUBREGION REGION_WB ECONOMY INCOME_GRP POP_EST GDP_MD
ADM0_ISO
CRI Costa Rica North America Americas Central America Latin America & Caribbean 5. Emerging region: G20 3. Upper middle income 5,047,561.00 61801
NIC Nicaragua North America Americas Central America Latin America & Caribbean 6. Developing region 4. Lower middle income 6,545,502.00 12520
PAN Panama North America Americas Central America Latin America & Caribbean 6. Developing region 3. Upper middle income 4,246,439.00 66800
# Lista de etiquetas de filas y lista de etiquetas de columnas
paises.loc[['CRI', 'NIC', 'PAN'], ['NAME', 'POP_EST']]
NAME POP_EST
ADM0_ISO
CRI Costa Rica 5,047,561.00
NIC Nicaragua 6,545,502.00
PAN Panama 4,246,439.00
# Nombres y poblaciones de países de América Central
poblaciones_america_central = paises.loc[['PAN', 'CRI', 'NIC', 'HND', 'SLV', 'GTM', 'BLZ'], ['NAME', 'POP_EST']]

poblaciones_america_central
NAME POP_EST
ADM0_ISO
PAN Panama 4,246,439.00
CRI Costa Rica 5,047,561.00
NIC Nicaragua 6,545,502.00
HND Honduras 9,746,117.00
SLV El Salvador 6,453,553.00
GTM Guatemala 16,604,026.00
BLZ Belize 390,353.00

Ejercicios

  1. Seleccione los países de la península ibérica y las columnas correspondientes a sus nombres y a su producto interno bruto.

Mediante expresiones lógicas#

Un dataframe puede filtrarse mediante expresiones lógicas, las cuales pueden incluir los operadores:

Y lógico (AND): &
O lógico (OR): |
No lógico (NOT): ~

# Países con más de 200 millones de habitantes
paises_muy_poblados = paises[paises['POP_EST'] > 200000000]

paises_muy_poblados
NAME CONTINENT REGION_UN SUBREGION REGION_WB ECONOMY INCOME_GRP POP_EST GDP_MD
ADM0_ISO
IDN Indonesia Asia Asia South-Eastern Asia East Asia & Pacific 4. Emerging region: MIKT 4. Lower middle income 270,625,568.00 1119190
IND India Asia Asia Southern Asia South Asia 3. Emerging region: BRIC 4. Lower middle income 1,366,417,754.00 2868929
CHN China Asia Asia Eastern Asia East Asia & Pacific 3. Emerging region: BRIC 3. Upper middle income 1,405,862,845.00 14762473
BRA Brazil South America Americas South America Latin America & Caribbean 3. Emerging region: BRIC 3. Upper middle income 211,049,527.00 1839758
NGA Nigeria Africa Africa Western Africa Sub-Saharan Africa 5. Emerging region: G20 4. Lower middle income 200,963,599.00 448120
PAK Pakistan Asia Asia Southern Asia South Asia 5. Emerging region: G20 4. Lower middle income 216,565,318.00 278221
USA United States of America North America Americas Northern America North America 1. Developed region: G7 1. High income: OECD 331,595,460.00 21542705
# Países con más de 200 millones de habitantes, incluyendo solo NAME, CONTINENT y POP_EST
paises_muy_poblados = paises.loc[paises['POP_EST'] > 200000000, ['NAME', 'CONTINENT', 'POP_EST']]

paises_muy_poblados
NAME CONTINENT POP_EST
ADM0_ISO
IDN Indonesia Asia 270,625,568.00
IND India Asia 1,366,417,754.00
CHN China Asia 1,405,862,845.00
BRA Brazil South America 211,049,527.00
NGA Nigeria Africa 200,963,599.00
PAK Pakistan Asia 216,565,318.00
USA United States of America North America 331,595,460.00
# Países asiáticos con más de 200 millones de habitantes, incluyendo solo NAME, CONTINENT y POP_EST
paises_asiaticos_muy_poblados = paises.loc[
    (paises['POP_EST'] > 200000000) & (paises['CONTINENT'] == 'Asia'), 
    ['NAME', 'CONTINENT', 'POP_EST']
]

paises_asiaticos_muy_poblados
NAME CONTINENT POP_EST
ADM0_ISO
IDN Indonesia Asia 270,625,568.00
IND India Asia 1,366,417,754.00
CHN China Asia 1,405,862,845.00
PAK Pakistan Asia 216,565,318.00
# Países asiáticos o africanos con más de 200 millones de habitantes, incluyendo solo NAME, CONTINENT y POP_EST
paises_asiaticos_africanos_muy_poblados = paises.loc[
    (paises['POP_EST'] > 200000000) & ((paises['CONTINENT'] == 'Asia') | (paises['CONTINENT'] == 'Africa')), 
    ['NAME', 'CONTINENT', 'POP_EST']
]

paises_asiaticos_africanos_muy_poblados
NAME CONTINENT POP_EST
ADM0_ISO
IDN Indonesia Asia 270,625,568.00
IND India Asia 1,366,417,754.00
CHN China Asia 1,405,862,845.00
NGA Nigeria Africa 200,963,599.00
PAK Pakistan Asia 216,565,318.00

Métodos head(), tail() y sample()#

Los métodos head(), tail() y sample(), descritos anteriormente, también pueden emplearse para crear subconjuntos.

Ejercicios

  1. Cree un subconjunto de los países con producto interno bruto (GDP_MD) menor a 1000 millones de dólares.

  2. Cree un subconjunto de los países con producto interno bruto menor a 1000 millones de dólares y con más de un millón de habitantes.

  3. Cree un subconjunto de los países de América Central, excepto Belice.

  4. Cree un subconjunto de los siete países de América Central y, además, República Dominicana.

Ordenamiento#

El método pandas.DataFrame.sort_values() ordena un dataframe de pandas por una o por varias columnas, en orden ascendente o descendente.

# Ordenamiento ascendente de países por nombre
paises.sort_values(by='NAME')
NAME CONTINENT REGION_UN SUBREGION REGION_WB ECONOMY INCOME_GRP POP_EST GDP_MD
ADM0_ISO
AFG Afghanistan Asia Asia Southern Asia South Asia 7. Least developed region 5. Low income 38,041,754.00 19291
ALB Albania Europe Europe Southern Europe Europe & Central Asia 6. Developing region 4. Lower middle income 2,854,191.00 15279
DZA Algeria Africa Africa Northern Africa Middle East & North Africa 6. Developing region 3. Upper middle income 43,053,054.00 171091
AND Andorra Europe Europe Southern Europe Europe & Central Asia 2. Developed region: nonG7 2. High income: nonOECD 77,142.00 3154
AGO Angola Africa Africa Middle Africa Sub-Saharan Africa 7. Least developed region 3. Upper middle income 31,825,295.00 88815
... ... ... ... ... ... ... ... ... ...
B28 W. Sahara Africa Africa Northern Africa Middle East & North Africa 7. Least developed region 5. Low income 603,253.00 907
YEM Yemen Asia Asia Western Asia Middle East & North Africa 7. Least developed region 4. Lower middle income 29,161,922.00 22581
ZMB Zambia Africa Africa Eastern Africa Sub-Saharan Africa 7. Least developed region 4. Lower middle income 17,861,030.00 23309
ZWE Zimbabwe Africa Africa Eastern Africa Sub-Saharan Africa 5. Emerging region: G20 5. Low income 14,645,468.00 21440
SWZ eSwatini Africa Africa Southern Africa Sub-Saharan Africa 6. Developing region 4. Lower middle income 1,148,130.00 4471

201 rows × 9 columns

# Ordenamiento ascendente de países por nombre y despliegue de las 5 primeras filas
paises.sort_values(by='NAME').head()
NAME CONTINENT REGION_UN SUBREGION REGION_WB ECONOMY INCOME_GRP POP_EST GDP_MD
ADM0_ISO
AFG Afghanistan Asia Asia Southern Asia South Asia 7. Least developed region 5. Low income 38,041,754.00 19291
ALB Albania Europe Europe Southern Europe Europe & Central Asia 6. Developing region 4. Lower middle income 2,854,191.00 15279
DZA Algeria Africa Africa Northern Africa Middle East & North Africa 6. Developing region 3. Upper middle income 43,053,054.00 171091
AND Andorra Europe Europe Southern Europe Europe & Central Asia 2. Developed region: nonG7 2. High income: nonOECD 77,142.00 3154
AGO Angola Africa Africa Middle Africa Sub-Saharan Africa 7. Least developed region 3. Upper middle income 31,825,295.00 88815
# Ordenamiento descendente de países por nombre y despliegue de las 5 primeras filas
paises.sort_values(by='NAME', ascending=False).head()
NAME CONTINENT REGION_UN SUBREGION REGION_WB ECONOMY INCOME_GRP POP_EST GDP_MD
ADM0_ISO
SWZ eSwatini Africa Africa Southern Africa Sub-Saharan Africa 6. Developing region 4. Lower middle income 1,148,130.00 4471
ZWE Zimbabwe Africa Africa Eastern Africa Sub-Saharan Africa 5. Emerging region: G20 5. Low income 14,645,468.00 21440
ZMB Zambia Africa Africa Eastern Africa Sub-Saharan Africa 7. Least developed region 4. Lower middle income 17,861,030.00 23309
YEM Yemen Asia Asia Western Asia Middle East & North Africa 7. Least developed region 4. Lower middle income 29,161,922.00 22581
B28 W. Sahara Africa Africa Northern Africa Middle East & North Africa 7. Least developed region 5. Low income 603,253.00 907
# Ordenamiento de países por continente y nombre
paises.sort_values(by=['CONTINENT', 'NAME'], ascending=[True, True])[['CONTINENT', 'NAME']]
CONTINENT NAME
ADM0_ISO
DZA Africa Algeria
AGO Africa Angola
BEN Africa Benin
BWA Africa Botswana
BFA Africa Burkina Faso
... ... ...
PRY South America Paraguay
PER South America Peru
SUR South America Suriname
URY South America Uruguay
VEN South America Venezuela

201 rows × 2 columns

Ejercicios

  1. Cree un subconjunto de todos los países del mundo ordenado descendentemente por la cantidad de habitantes.

  2. Cree un subconjunto de todos los países del mundo ordenado ascendentemente por el producto interno bruto.

Creación y modificación de columnas#

En un dataframe, pueden crearse o modificarse columnas de varias formas. Una de las más comunes es a través de operaciones con otras columnas.

Ejemplo: PIB per cápita#

En el dataframe paises puede crearse una nueva columna llamada GDP_MD_PC con el resultado del cálculo del Producto Interno Bruto (PIB) per cápita para cada país.

# Creación de la columna GDP_PC (PIB per cápita en dólares)
paises['GDP_PC'] = (paises['GDP_MD'] * 1000000) / paises['POP_EST']

Para modularizar el código, es conveniente crear una función que realice el cálculo del PIB per cápita.

def pib_per_capita(pib, poblacion):
    """
    Retorna el PIB per cápita dados el PIB de un país (en millones de dólares) y su población.
    """

    return (pib * 1000000) / poblacion
# Creación de la columna GDP_PC (PIB per cápita en dólares)
# mediante la función pib_per_capita()
paises['GDP_PC'] = pib_per_capita(paises['GDP_MD'], paises['POP_EST'])
# Despliegue de la nueva columna
paises[['NAME', 'GDP_MD', 'POP_EST', 'GDP_PC']]
NAME GDP_MD POP_EST GDP_PC
ADM0_ISO
IDN Indonesia 1119190 270,625,568.00 4,135.57
MYS Malaysia 364681 31,949,777.00 11,414.20
CHL Chile 282318 18,952,038.00 14,896.45
BOL Bolivia 40895 11,513,100.00 3,552.04
PER Peru 226848 32,510,453.00 6,977.69
... ... ... ... ...
NRU Nauru 118 12,581.00 9,379.22
FSM Micronesia 401 113,815.00 3,523.26
VUT Vanuatu 934 299,882.00 3,114.56
PLW Palau 268 18,008.00 14,882.27
BHR Bahrain 38574 1,641,172.00 23,503.93

201 rows × 4 columns

Ejemplo: idiomas oficiales#

Para crear una nueva columna llamada LANGUAGES, con los idiomas oficiales de cada país, se define una función llamada obtener_idiomas_pais(), la cual recibe como entrada el código ISO 3166-1 alpha-3 (cca3) del país (el cual se encuentra en el índice del dataframe paises) y consulta el API REST Countries para retornar una hilera de texto con los nombres de los idiomas.

import requests

def obtener_idiomas_pais(cca3):
    """
    Obtiene una cadena con la lista de lenguajes oficiales de un país dado su código cca3.
    """

    # URL del API REST Countries
    url = f'https://restcountries.com/v3.1/alpha/{cca3}'
    
    # Respuesta del API a la solicitud
    respuesta = requests.get(url)
    
    # Revisión de la respuesta
    if respuesta.status_code == 200:
        datos = respuesta.json()
        
        if datos and 'languages' in datos[0]:
            lenguajes = datos[0]['languages']
            lista_lenguajes = list(lenguajes.values())
            return ', '.join(lista_lenguajes)
        else:
            return None
    else:
        return None

Ahora, para crear o modificar la nueva columna LANGUAGES, se utiliza la función map() de Python, la cual aplica una función a cada uno de los elementos de una estructura de datos iterable (ej. tuplas, listas, series, dataframes). En este caso, aplica la función obtener_idiomas_pais() al dataframe de países, recibiendo como entrada el índice del dataframe paises (paises.index).

# Creación de la columna LANGUAGES mediante la función obtener_idiomas_pais()
paises['LANGUAGES'] = paises.index.map(obtener_idiomas_pais)
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
Cell In[39], line 2
      1 # Creación de la columna LANGUAGES mediante la función obtener_idiomas_pais()
----> 2 paises['LANGUAGES'] = paises.index.map(obtener_idiomas_pais)

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/site-packages/pandas/core/indexes/base.py:6491, in Index.map(self, mapper, na_action)
   6455 """
   6456 Map values using an input mapping or function.
   6457 
   (...)
   6487 Index(['A', 'B', 'C'], dtype='object')
   6488 """
   6489 from pandas.core.indexes.multi import MultiIndex
-> 6491 new_values = self._map_values(mapper, na_action=na_action)
   6493 # we can return a MultiIndex
   6494 if new_values.size and isinstance(new_values[0], tuple):

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/site-packages/pandas/core/base.py:921, in IndexOpsMixin._map_values(self, mapper, na_action, convert)
    918 if isinstance(arr, ExtensionArray):
    919     return arr.map(mapper, na_action=na_action)
--> 921 return algorithms.map_array(arr, mapper, na_action=na_action, convert=convert)

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/site-packages/pandas/core/algorithms.py:1743, in map_array(arr, mapper, na_action, convert)
   1741 values = arr.astype(object, copy=False)
   1742 if na_action is None:
-> 1743     return lib.map_infer(values, mapper, convert=convert)
   1744 else:
   1745     return lib.map_infer_mask(
   1746         values, mapper, mask=isna(values).view(np.uint8), convert=convert
   1747     )

File lib.pyx:2972, in pandas._libs.lib.map_infer()

Cell In[38], line 12, in obtener_idiomas_pais(cca3)
      9 url = f'https://restcountries.com/v3.1/alpha/{cca3}'
     11 # Respuesta del API a la solicitud
---> 12 respuesta = requests.get(url)
     14 # Revisión de la respuesta
     15 if respuesta.status_code == 200:

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/site-packages/requests/api.py:73, in get(url, params, **kwargs)
     62 def get(url, params=None, **kwargs):
     63     r"""Sends a GET request.
     64 
     65     :param url: URL for the new :class:`Request` object.
   (...)
     70     :rtype: requests.Response
     71     """
---> 73     return request("get", url, params=params, **kwargs)

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/site-packages/requests/api.py:59, in request(method, url, **kwargs)
     55 # By using the 'with' statement we are sure the session is closed, thus we
     56 # avoid leaving sockets open which can trigger a ResourceWarning in some
     57 # cases, and look like a memory leak in others.
     58 with sessions.Session() as session:
---> 59     return session.request(method=method, url=url, **kwargs)

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/site-packages/requests/sessions.py:589, in Session.request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
    584 send_kwargs = {
    585     "timeout": timeout,
    586     "allow_redirects": allow_redirects,
    587 }
    588 send_kwargs.update(settings)
--> 589 resp = self.send(prep, **send_kwargs)
    591 return resp

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/site-packages/requests/sessions.py:703, in Session.send(self, request, **kwargs)
    700 start = preferred_clock()
    702 # Send the request
--> 703 r = adapter.send(request, **kwargs)
    705 # Total elapsed time of the request (approximately)
    706 elapsed = preferred_clock() - start

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/site-packages/requests/adapters.py:667, in HTTPAdapter.send(self, request, stream, timeout, verify, cert, proxies)
    664     timeout = TimeoutSauce(connect=timeout, read=timeout)
    666 try:
--> 667     resp = conn.urlopen(
    668         method=request.method,
    669         url=url,
    670         body=request.body,
    671         headers=request.headers,
    672         redirect=False,
    673         assert_same_host=False,
    674         preload_content=False,
    675         decode_content=False,
    676         retries=self.max_retries,
    677         timeout=timeout,
    678         chunked=chunked,
    679     )
    681 except (ProtocolError, OSError) as err:
    682     raise ConnectionError(err, request=request)

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/site-packages/urllib3/connectionpool.py:789, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)
    786 response_conn = conn if not release_conn else None
    788 # Make the request on the HTTPConnection object
--> 789 response = self._make_request(
    790     conn,
    791     method,
    792     url,
    793     timeout=timeout_obj,
    794     body=body,
    795     headers=headers,
    796     chunked=chunked,
    797     retries=retries,
    798     response_conn=response_conn,
    799     preload_content=preload_content,
    800     decode_content=decode_content,
    801     **response_kw,
    802 )
    804 # Everything went great!
    805 clean_exit = True

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/site-packages/urllib3/connectionpool.py:466, in HTTPConnectionPool._make_request(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)
    463 try:
    464     # Trigger any extra validation we need to do.
    465     try:
--> 466         self._validate_conn(conn)
    467     except (SocketTimeout, BaseSSLError) as e:
    468         self._raise_timeout(err=e, url=url, timeout_value=conn.timeout)

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/site-packages/urllib3/connectionpool.py:1095, in HTTPSConnectionPool._validate_conn(self, conn)
   1093 # Force connect early to allow us to validate the connection.
   1094 if conn.is_closed:
-> 1095     conn.connect()
   1097 # TODO revise this, see https://github.com/urllib3/urllib3/issues/2791
   1098 if not conn.is_verified and not conn.proxy_is_verified:

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/site-packages/urllib3/connection.py:615, in HTTPSConnection.connect(self)
    613 def connect(self) -> None:
    614     sock: socket.socket | ssl.SSLSocket
--> 615     self.sock = sock = self._new_conn()
    616     server_hostname: str = self.host
    617     tls_in_tls = False

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/site-packages/urllib3/connection.py:196, in HTTPConnection._new_conn(self)
    191 """Establish a socket connection and set nodelay settings on it.
    192 
    193 :return: New socket connection.
    194 """
    195 try:
--> 196     sock = connection.create_connection(
    197         (self._dns_host, self.port),
    198         self.timeout,
    199         source_address=self.source_address,
    200         socket_options=self.socket_options,
    201     )
    202 except socket.gaierror as e:
    203     raise NameResolutionError(self.host, self, e) from e

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/site-packages/urllib3/util/connection.py:60, in create_connection(address, timeout, source_address, socket_options)
     57 except UnicodeError:
     58     raise LocationParseError(f"'{host}', label empty or too long") from None
---> 60 for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
     61     af, socktype, proto, canonname, sa = res
     62     sock = None

File ~/miniconda3/envs/gf0657-2024-ii/lib/python3.12/socket.py:976, in getaddrinfo(host, port, family, type, proto, flags)
    973 # We override this function since we want to translate the numeric family
    974 # and socket type values to enum constants.
    975 addrlist = []
--> 976 for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
    977     af, socktype, proto, canonname, sa = res
    978     addrlist.append((_intenum_converter(af, AddressFamily),
    979                      _intenum_converter(socktype, SocketKind),
    980                      proto, canonname, sa))

KeyboardInterrupt: 
# Despliegue de la nueva columna
paises[['NAME', 'LANGUAGES']]
NAME LANGUAGES
ADM0_ISO
IDN Indonesia Indonesian
MYS Malaysia English, Malay
CHL Chile Spanish
BOL Bolivia Aymara, Guaraní, Quechua, Spanish
PER Peru Aymara, Quechua, Spanish
... ... ...
NRU Nauru English, Nauru
FSM Micronesia English
VUT Vanuatu Bislama, English, French
PLW Palau English, Palauan
BHR Bahrain Arabic

201 rows × 2 columns

Ejercicios

  1. Defina una función llamada obtener_capital_pais() que reciba el código cca3 de un país y retorne su capital mediante una consulta al API REST Countries. Utilíce esta función para crear en el dataframe paises una nueva columna llamada CAPITAL, con la ciudad capital de cada país.

Agrupación y agregación#

El proceso de agrupación y agregación consiste en dividir un conjunto de datos en grupos basados en uno o más criterios, para luego realizar operaciones en cada grupo. En pandas, este proceso se realiza mediante el método pandas.DataFrame.groupby().

Por ejemplo, el dataframe de países puede agruparse por continente para calcular en cada uno la suma de la población.

# Suma de población por continente
suma_poblacion_por_continente = paises.groupby('CONTINENT')['POP_EST'].sum()

# Despliegue de los resultados, ordenados descendentemente por población
suma_poblacion_por_continente.sort_values(ascending=False)
CONTINENT
Asia                      4,562,304,603.00
Africa                    1,307,986,092.30
Europe                      747,708,092.00
North America               584,776,221.00
South America               427,063,263.00
Oceania                      41,589,500.00
Seven seas (open ocean)       1,894,289.00
Antarctica                        4,490.00
Name: POP_EST, dtype: float64

El argumento de groupby() es usualmente una columna categórica (ej. CONTINENT) cuyos valores pasan a ser los grupos. En cada grupo se aplica una función de agregación (ej. sum()) para los valores de una columna numérica (ej. POP_EST).

Algunas funciones comunes de agregación son:

  • sum(): suma.

  • mean(): promedio.

  • count(): número de elementos.

  • max(), min(): valores máximo y mínimo.

  • median(): mediana.

  • std(): desviación estándar.

  • agg(): para aplicar múltiples funciones o funciones personalizadas.

El métoddo groupby() permite agrupar también por múltiples columnas.

# Suma de población por región y subregión de la ONU
suma_poblacion_por_region_subregion = paises.groupby(['REGION_UN', 'SUBREGION'])['POP_EST'].sum()

suma_poblacion_por_region_subregion
REGION_UN   SUBREGION                
Africa      Eastern Africa                435,175,445.30
            Middle Africa                 174,308,432.00
            Northern Africa               241,801,558.00
            Southern Africa                66,629,895.00
            Western Africa                391,434,098.00
Americas    Caribbean                      38,982,419.00
            Central America               176,609,080.00
            Northern America              369,184,722.00
            South America                 427,063,263.00
Antarctica  Antarctica                          4,490.00
Asia        Central Asia                   73,814,587.00
            Eastern Asia                1,636,296,580.00
            South-Eastern Asia            661,911,038.00
            Southern Asia               1,918,690,648.00
            Western Asia                  272,122,703.00
Europe      Eastern Europe                291,080,093.00
            Northern Europe               105,802,448.00
            Southern Europe               152,729,852.00
            Western Europe                198,095,699.00
Oceania     Australia and New Zealand      30,319,695.00
            Melanesia                      10,635,767.00
            Micronesia                        320,801.00
            Polynesia                         313,237.00
Name: POP_EST, dtype: float64

También es posible aplicar múltiples funciones de agregación.

# Suma y promedio de población por región y subregión de la ONU
suma_promedio_poblacion_por_region_subregion = paises.groupby(['REGION_UN', 'SUBREGION'])['POP_EST'].agg(['sum', 'mean'])

suma_promedio_poblacion_por_region_subregion
sum mean
REGION_UN SUBREGION
Africa Eastern Africa 435,175,445.30 22,903,970.81
Middle Africa 174,308,432.00 19,367,603.56
Northern Africa 241,801,558.00 34,543,079.71
Southern Africa 66,629,895.00 13,325,979.00
Western Africa 391,434,098.00 24,464,631.12
Americas Caribbean 38,982,419.00 2,998,647.62
Central America 176,609,080.00 22,076,135.00
Northern America 369,184,722.00 184,592,361.00
South America 427,063,263.00 35,588,605.25
Antarctica Antarctica 4,490.00 4,490.00
Asia Central Asia 73,814,587.00 14,762,917.40
Eastern Asia 1,636,296,580.00 272,716,096.67
South-Eastern Asia 661,911,038.00 60,173,730.73
Southern Asia 1,918,690,648.00 213,187,849.78
Western Asia 272,122,703.00 14,322,247.53
Europe Eastern Europe 291,080,093.00 29,108,009.30
Northern Europe 105,802,448.00 10,580,244.80
Southern Europe 152,729,852.00 9,545,615.75
Western Europe 198,095,699.00 22,010,633.22
Oceania Australia and New Zealand 30,319,695.00 15,159,847.50
Melanesia 10,635,767.00 2,658,941.75
Micronesia 320,801.00 64,160.20
Polynesia 313,237.00 104,412.33

Ejercicios

  1. Calcule el promedio del PIB (GDP_MD) por continente. Muestre los resultados por orden alfabético de continente.

  2. Calcule la suma y el promedio del PIB (GDP_MD) por continente. Muestre los resultados por orden descendente de suma del PIB.

  3. Calcule el promedio del PIB (GDP_MD) por grupo de ingresos (INCOME_GRP). Muestre los resultados en orden descendente de promedio del PIB.

  4. Calcule el promedio del PIB (GDP_MD) para las subregiones de las regiones de la ONU del continente americano. Muestre los resultados en orden descendente de promedio del PIB.

Unión (join)#

La unión (en inglés, join) de datos ubicados en diferentes fuentes (ej. diferentes archivos) es una tarea común en análisis de información. Las uniones pueden ser de filas, columnas o de ambas. Usualmente, este tipo de operaciones se realiza con base en columnas que son comunes en los conjuntos de datos que se desea unir. A estas columnas se les llama “llaves” o “claves” (en inglés, keys).

Hay varios tipos de uniones de datos:

  • Left join: mantiene todas las filas del conjunto de datos del lado izquierdo y les agrega las columnas del conjunto de datos del lado derecho, en las filas en las que hay coincidencia en las llaves.

  • Right join: mantiene todas las filas del conjunto de datos del lado derecho y agrega las columnas del conjunto de datos del lado izquierdo, en las filas en las que hay coincidencia en las llaves.

  • Inner join: incluye las filas que coinciden en ambos conjuntos de datos.

  • Full join: incluye todas las filas de ambos conjuntos de datos.

Los diferentes tipos de unión se ilustran en la Fig. 24 mediante diagramas de Venn.

../../_images/join.jpg

Fig. 24 Tipos de uniones de datos. Imagen de hostingplus.#

La biblioteca pandas incluye varios métodos para unir series y dataframes:

Para ejemplificar el concepto de unión de datos, al dataframe paises se le agregará una columna correspondiente a la esperanza de vida al nacer en cada país. Esta columna proviene de los datos de indicadores del Banco Mundial.

# Carga de datos de esperanza de vida al nacer por país

esperanza_vida = pd.read_csv(
    "https://raw.githubusercontent.com/gf0657-programacionsig/2024-ii/refs/heads/main/datos/world-bank/paises-esperanza-vida.csv"
)

El archivo CSV del Banco Mundial tiene más de 60 columnas. Para simplificar el análisis, se conservan solamente las columnas Country Code (código cca3) y 2022 (esperanza de vida al nacer en 2022). La primera se utiliza como índice.

# Reducción de columnas de esperanza_vida
esperanza_vida = esperanza_vida[['Country Code', '2022']]

# Se usa la columna 'Country Code' como índice
esperanza_vida.set_index('Country Code', inplace=True)

# Muestra de los datos
esperanza_vida.sample(10)
2022
Country Code
IBT 70.51
NPL 70.48
MNA 72.30
LCA 71.29
ECA 74.11
PAK 66.43
ISL 82.17
IDA 64.05
OMN 73.94
ARB 71.23

Seguidamente, se utiliza el método pandas.Dataframe.join() para unir paises con paises_esperanza_vida. Se elige este método debido a que su sintaxis es muy sencilla cuando las llaves de ambos dataframes con los índices.

# Unión de los dataframes paises y esperanza_vida
paises = paises.join(esperanza_vida, how="left")

En este caso paises es el conjunto del “lado izquierdo” y esperanza_vida el del “lado derecho”. El argumento how="left" indica que se está realizando un left join, por lo que se conservan todas las filas del conjunto de lado izquierdo. Si el código cca3 de algún país de países no está en esperanza_vida, la columna unida tendrá un valor nulo.

La nueva columna se renombra con el método pandas.DataFrame.rename(), para que sea similar a las otras.

# Cambio de nombre de la nueva columna

paises.rename(columns={'2022': 'LIFE_EXPECTANCY'}, inplace=True)
# Muestra aleatoria de 10 filas
paises.sample(5)
NAME CONTINENT REGION_UN SUBREGION REGION_WB ECONOMY INCOME_GRP POP_EST GDP_MD GDP_PC LANGUAGES LIFE_EXPECTANCY
ADM0_ISO
IRL Ireland Europe Europe Northern Europe Europe & Central Asia 2. Developed region: nonG7 1. High income: OECD 4,941,444.00 388698 78,660.81 English, Irish 83.06
MOZ Mozambique Africa Africa Eastern Africa Sub-Saharan Africa 7. Least developed region 5. Low income 30,366,036.00 15291 503.56 Portuguese 59.62
CPV Cabo Verde Africa Africa Western Africa Sub-Saharan Africa 6. Developing region 4. Lower middle income 549,935.00 1981 3,602.24 Portuguese 74.72
JAM Jamaica North America Americas Caribbean Latin America & Caribbean 6. Developing region 3. Upper middle income 2,948,279.00 16458 5,582.24 English, Jamaican Patois 70.63
BHS Bahamas North America Americas Caribbean Latin America & Caribbean 6. Developing region 2. High income: nonOECD 389,482.00 13578 34,861.69 English 74.36
# Países con esperanza de vida más alta
paises.sort_values(by='LIFE_EXPECTANCY', ascending=False).head(10)[['NAME', 'CONTINENT', 'LIFE_EXPECTANCY']]
NAME CONTINENT LIFE_EXPECTANCY
ADM0_ISO
LIE Liechtenstein Europe 84.32
JPN Japan Asia 84.00
CHE Switzerland Europe 83.45
AUS Australia Oceania 83.20
SWE Sweden Europe 83.11
ESP Spain Europe 83.08
IRL Ireland Europe 83.06
LUX Luxembourg Europe 83.05
ITA Italy Europe 82.90
SGP Singapore Asia 82.90
# Países con esperanza de vida más baja
paises.sort_values(by='LIFE_EXPECTANCY', ascending=True).head(10)[['NAME', 'CONTINENT', 'LIFE_EXPECTANCY']]
NAME CONTINENT LIFE_EXPECTANCY
ADM0_ISO
TCD Chad Africa 53.00
LSO Lesotho Africa 53.04
NGA Nigeria Africa 53.63
CAF Central African Rep. Africa 54.48
SSD S. Sudan Africa 55.57
SOM Somaliland Africa 56.11
SOM Somalia Africa 56.11
SWZ eSwatini Africa 56.36
NAM Namibia Africa 58.06
CIV Côte d'Ivoire Africa 58.92

Ejercicios

  1. Mediante uniones de datos, agregue al dataframe paises columnas correspondientes a:

  • Tasa de alfabetización de adultos.

  • Tasa de mortalidad infantil.

Busque los archivos de datos necesarios en Banco Mundial - Datos de indicadores. Sugerencia: con un editor de texto (ej. VS Code) elimine las filas que no forman parte del formato CSV en la parte superior de los archivos.

Exportación#

pandas proporciona varios métodos para exportar dataframes a otros formatos. Por ejemplo, el método pandas.DataFrame.to_csv() exporta un dataframe a un archivo de valores separados por comas (CSV). Otros métodos similares pueden exportar a otros formatos.

# Exportación al formato CSV
paises.to_csv('paises-ampliado.csv')

# Exportación al formato JSON
paises.to_json('paises-ampliado.json', orient='records')

Recursos de interés#

Banco Mundial - Datos de indicadores. (s. f.). Recuperado 6 de octubre de 2024, de https://datos.bancomundial.org/indicador

Natural Earth - Free vector and raster map data. (s. f.). Recuperado 6 de octubre de 2024, de https://www.naturalearthdata.com/