23. Pandas Avanzado - Filtrado, Agrupación y Análisis#
“Los algoritmos que actualmente controlan el mundo se pueden dividir en dos grandes familias. Unos procesan datos para entender el mundo; otros procesan datos para tomar decisiones. Los más poderosos hacen ambas cosas.”
—Yuval Noah Harari, Homo Deus (2016)
23.1. Objetivos de Aprendizaje#
Al finalizar este capítulo, serás capaz de:
Filtrar datos usando condiciones simples y múltiples
Ordenar DataFrames por una o más columnas
Agrupar datos con
groupby()para calcular estadísticasCrear tablas dinámicas con
pivot_table()Manejar valores faltantes (NaN)
Analizar datos religiosos por país y región
23.2. Preparación del Entorno#
En este capítulo trabajaremos con el dataset WRP National, que contiene datos de religiones por país desde 1945 hasta 2010.
import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings('ignore')
# Configuración para mostrar más columnas
pd.set_option('display.max_columns', 15)
pd.set_option('display.width', None)
# Cargar el dataset de religiones por país
df = pd.read_csv("WRP_national.csv")
# Exploración inicial
print(f"Dimensiones: {df.shape[0]} filas x {df.shape[1]} columnas")
print(f"Países únicos: {df['name'].nunique()}")
print(f"Período: {df['year'].min()} - {df['year'].max()}")
Dimensiones: 1995 filas x 84 columnas
Países únicos: 200
Período: 1945 - 2010
# Ver las primeras filas
df.head()
| year | state | name | chrstprot | chrstcat | chrstorth | chrstang | ... | dualrelig | datatype | sourcereliab | recreliab | reliabilevel | Version | sourcecode | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1945 | 2 | USA | 66069671 | 38716742 | 1121898 | 2400000 | ... | 0 | 34 | 2 | 10 | Medium | 1.1 | 13 |
| 1 | 1950 | 2 | USA | 73090083 | 42635882 | 3045420 | 3045420 | ... | 0 | 34 | 6 | 28 | Low | 1.1 | 18 |
| 2 | 1955 | 2 | USA | 79294628 | 46402368 | 3454916 | 2572767 | ... | 0 | 134 | 5 | 10 | Medium | 1.1 | 15 |
| 3 | 1960 | 2 | USA | 90692928 | 50587880 | 3334535 | 2710065 | ... | 0 | 134 | 2 | 10 | Medium | 1.1 | 13 |
| 4 | 1965 | 2 | USA | 94165803 | 64761783 | 4792868 | 2822149 | ... | 0 | 134 | 8 | 28 | Low | 1.1 | 20 |
5 rows × 84 columns
23.2.1. Entendiendo las Columnas del Dataset#
Fuente de los Datos
Zeev Maoz y Errol A. Henderson (2013). “The World Religion Dataset, 1945-2010: Logic, Estimates, and Trends”. International Interactions, 39: 265-291.
Disponible en: https://correlatesofwar.org/data-sets/world-religion-data/
Columna |
Descripción |
|---|---|
|
Año del registro |
|
Código numérico del país (COW) |
|
Código de 3 letras del país |
|
Población total |
|
% de cristianos |
|
% de musulmanes |
|
% de budistas |
|
% de hindúes |
|
% sin religión |
23.3. Filtrado de Datos#
23.3.1. Analogía Histórica: El Censo Colonial#
Imagina que eres un funcionario colonial en el siglo XVIII y necesitas encontrar información específica en los registros del censo. Por ejemplo, quieres saber cuántas personas vivían en pueblos con más de 1,000 habitantes.
El filtrado en Pandas funciona de manera similar: te permite seleccionar solo las filas que cumplen ciertas condiciones.
23.3.2. Filtrado Simple: Una Condición#
# Filtrar datos de Chile (código: CHL)
chile = df[df['name'] == 'CHL']
print(f"Registros de Chile: {len(chile)}")
chile[['year', 'name', 'pop', 'chrstgenpct', 'nonreligpct']]
Registros de Chile: 14
| year | name | pop | chrstgenpct | nonreligpct | |
|---|---|---|---|---|---|
| 371 | 1945 | CHL | 5540000 | 0.9196 | 0.0000 |
| 372 | 1950 | CHL | 6091000 | 0.9118 | 0.0000 |
| 373 | 1955 | CHL | 6743000 | 0.9436 | 0.0000 |
| 374 | 1960 | CHL | 7614000 | 0.9822 | 0.0000 |
| 375 | 1965 | CHL | 8579000 | 0.9373 | 0.0000 |
| 376 | 1970 | CHL | 9504000 | 0.9395 | 0.0338 |
| 377 | 1975 | CHL | 10350000 | 0.9325 | 0.0338 |
| 378 | 1980 | CHL | 11145000 | 0.9396 | 0.0383 |
| 379 | 1985 | CHL | 12122000 | 0.9367 | 0.0000 |
| 380 | 1990 | CHL | 13100000 | 0.9430 | 0.0334 |
| 381 | 1995 | CHL | 14210000 | 0.9560 | 0.0000 |
| 382 | 2000 | CHL | 15211000 | 0.9334 | 0.0300 |
| 383 | 2005 | CHL | 16267000 | 0.8775 | 0.0830 |
| 384 | 2010 | CHL | 17077416 | 0.9128 | 0.0600 |
# Filtrar datos del año 2010
datos_2010 = df[df['year'] == 2010]
print(f"Países en 2010: {len(datos_2010)}")
datos_2010[['name', 'pop', 'chrstgenpct', 'islmgenpct']].head(10)
Países en 2010: 194
| name | pop | chrstgenpct | islmgenpct | |
|---|---|---|---|---|
| 13 | USA | 312750000 | 0.7454 | 0.0090 |
| 27 | CAN | 34500000 | 0.7661 | 0.0194 |
| 35 | BHM | 313312 | 0.9660 | 0.0000 |
| 49 | CUB | 11241161 | 0.6589 | 0.0007 |
| 63 | HAI | 9760832 | 0.8200 | 0.0002 |
| 77 | DOM | 9956648 | 0.8700 | 0.0000 |
| 88 | JAM | 2868630 | 0.6881 | 0.0005 |
| 99 | TRI | 1305000 | 0.5588 | 0.0503 |
| 108 | BAR | 288705 | 0.6434 | 0.0080 |
| 115 | DMA | 73000 | 0.9200 | 0.0000 |
# Filtrar países con más del 90% de cristianos en 2010
muy_cristianos = df[(df['year'] == 2010) & (df['chrstgenpct'] > 0.90)]
print(f"Países con más del 90% de cristianos en 2010: {len(muy_cristianos)}")
muy_cristianos[['name', 'chrstgenpct', 'pop']].sort_values('chrstgenpct', ascending=False).head(10)
Países con más del 90% de cristianos en 2010: 40
| name | chrstgenpct | pop | |
|---|---|---|---|
| 1905 | ETM | 0.9800 | 1127779 |
| 255 | PAN | 0.9793 | 4255000 |
| 759 | ROM | 0.9751 | 21433182 |
| 656 | MLT | 0.9727 | 412911 |
| 269 | COL | 0.9701 | 46295000 |
| 1975 | NAU | 0.9699 | 9937 |
| 1960 | TUV | 0.9699 | 10067 |
| 164 | MEX | 0.9686 | 112336538 |
| 35 | BHM | 0.9660 | 313312 |
| 1957 | KIR | 0.9600 | 103000 |
23.3.3. Filtrado Múltiple: Combinando Condiciones#
Usamos operadores lógicos:
&→ AND (ambas condiciones deben cumplirse)|→ OR (al menos una condición debe cumplirse)~→ NOT (negación)
# Países de América Latina en 2010
paises_latam = ['MEX', 'ARG', 'BRA', 'CHL', 'COL', 'PER', 'VEN', 'ECU', 'BOL', 'URU', 'PAR']
latam_2010 = df[(df['year'] == 2010) & (df['name'].isin(paises_latam))]
print("América Latina en 2010:")
latam_2010[['name', 'pop', 'chrstgenpct', 'chrstcatpct', 'chrstprotpct']].sort_values('pop', ascending=False)
América Latina en 2010:
| name | pop | chrstgenpct | chrstcatpct | chrstprotpct | |
|---|---|---|---|---|---|
| 342 | BRA | 190755800 | 0.8823 | 0.5960 | 0.2680 |
| 164 | MEX | 112336538 | 0.9686 | 0.8272 | 0.1414 |
| 269 | COL | 46295000 | 0.9701 | 0.8200 | 0.1500 |
| 398 | ARG | 40399992 | 0.8515 | 0.7500 | 0.1000 |
| 328 | PER | 29402646 | 0.9380 | 0.8130 | 0.1250 |
| 283 | VEN | 28834000 | 0.9500 | 0.8000 | 0.1500 |
| 384 | CHL | 17077416 | 0.9128 | 0.7586 | 0.1061 |
| 314 | ECU | 14209151 | 0.9030 | 0.8700 | 0.0200 |
| 356 | BOL | 10312315 | 0.9426 | 0.8088 | 0.1332 |
| 370 | PAR | 6455292 | 0.9510 | 0.8800 | 0.0400 |
| 412 | URU | 3356679 | 0.8183 | 0.4710 | 0.1100 |
# Países con mayoría musulmana (>50%) Y población mayor a 50 millones en 2010
grandes_musulmanes = df[(df['year'] == 2010) &
(df['islmgenpct'] > 0.50) &
(df['pop'] > 50000000)]
print("Grandes países de mayoría musulmana en 2010:")
grandes_musulmanes[['name', 'pop', 'islmgenpct']].sort_values('pop', ascending=False)
Grandes países de mayoría musulmana en 2010:
| name | pop | islmgenpct | |
|---|---|---|---|
| 1903 | INS | 239960000 | 0.8399 |
| 1740 | PAK | 168446576 | 0.9569 |
| 1074 | NIG | 154110416 | 0.5080 |
| 1748 | BNG | 147290688 | 0.8970 |
| 1456 | EGY | 81277560 | 0.8643 |
| 1428 | TUR | 76787632 | 0.9858 |
| 1414 | IRN | 74073560 | 0.9900 |
23.4. Ordenando Datos#
El método sort_values() permite ordenar un DataFrame por una o más columnas.
# Ordenar países por población en 2010 (descendente)
top_poblacion = df[df['year'] == 2010].sort_values('pop', ascending=False)
print("Los 10 países más poblados en 2010:")
top_poblacion[['name', 'pop']].head(10)
Los 10 países más poblados en 2010:
| name | pop | |
|---|---|---|
| 1639 | CHN | 1345174272 |
| 1719 | IND | 1195000000 |
| 13 | USA | 312750000 |
| 1903 | INS | 239960000 |
| 342 | BRA | 190755800 |
| 1740 | PAK | 168446576 |
| 1074 | NIG | 154110416 |
| 1748 | BNG | 147290688 |
| 773 | RUS | 142400000 |
| 1706 | JPN | 127451704 |
# Ordenar por múltiples columnas
# Primero por año, luego por porcentaje de cristianos
ordenado = chile.sort_values(['year', 'chrstgenpct'], ascending=[True, False])
ordenado[['year', 'chrstgenpct', 'nonreligpct']]
| year | chrstgenpct | nonreligpct | |
|---|---|---|---|
| 371 | 1945 | 0.9196 | 0.0000 |
| 372 | 1950 | 0.9118 | 0.0000 |
| 373 | 1955 | 0.9436 | 0.0000 |
| 374 | 1960 | 0.9822 | 0.0000 |
| 375 | 1965 | 0.9373 | 0.0000 |
| 376 | 1970 | 0.9395 | 0.0338 |
| 377 | 1975 | 0.9325 | 0.0338 |
| 378 | 1980 | 0.9396 | 0.0383 |
| 379 | 1985 | 0.9367 | 0.0000 |
| 380 | 1990 | 0.9430 | 0.0334 |
| 381 | 1995 | 0.9560 | 0.0000 |
| 382 | 2000 | 0.9334 | 0.0300 |
| 383 | 2005 | 0.8775 | 0.0830 |
| 384 | 2010 | 0.9128 | 0.0600 |
23.5. Agrupación con groupby()#
23.5.1. Analogía Histórica: El Catastro#
En el Chile colonial, el catastro agrupaba propiedades por tipo (haciendas, chacras, solares) para calcular impuestos. De manera similar, groupby() agrupa filas por valores comunes y permite calcular estadísticas para cada grupo.
Proceso de groupby()
Dividir: Separar los datos en grupos según una columna
Aplicar: Calcular una función (suma, promedio, etc.) para cada grupo
Combinar: Unir los resultados en una nueva estructura
# Promedio de porcentaje cristiano por año (nivel mundial)
cristianos_por_año = df.groupby('year')['chrstgenpct'].mean()
print("Porcentaje promedio de cristianos por año:")
cristianos_por_año
Porcentaje promedio de cristianos por año:
year
1945 0.701698
1950 0.608386
1955 0.582484
1960 0.519113
1965 0.506852
1970 0.498916
1975 0.510285
1980 0.537344
1985 0.537712
1990 0.537367
1995 0.551703
2000 0.550735
2005 0.553080
2010 0.550301
Name: chrstgenpct, dtype: float64
# Múltiples estadísticas a la vez
stats_religiones = df.groupby('year').agg({
'chrstgenpct': 'mean',
'islmgenpct': 'mean',
'nonreligpct': 'mean',
'pop': 'sum'
}).round(4)
stats_religiones.columns = ['Cristianos %', 'Musulmanes %', 'Sin Religión %', 'Población Total']
print("Estadísticas por año:")
stats_religiones
Estadísticas por año:
| Cristianos % | Musulmanes % | Sin Religión % | Población Total | |
|---|---|---|---|---|
| year | ||||
| 1945 | 0.7017 | 0.1459 | 0.0295 | 1607867655 |
| 1950 | 0.6084 | 0.1738 | 0.0323 | 2220573024 |
| 1955 | 0.5825 | 0.1779 | 0.0473 | 2535824000 |
| 1960 | 0.5191 | 0.2185 | 0.0435 | 2920787124 |
| 1965 | 0.5069 | 0.2285 | 0.0420 | 3279601467 |
| 1970 | 0.4989 | 0.2483 | 0.0472 | 3655452232 |
| 1975 | 0.5103 | 0.2490 | 0.0449 | 4022668800 |
| 1980 | 0.5373 | 0.2392 | 0.0438 | 4265381362 |
| 1985 | 0.5377 | 0.2403 | 0.0511 | 4669065357 |
| 1990 | 0.5374 | 0.2484 | 0.0530 | 5312671680 |
| 1995 | 0.5517 | 0.2449 | 0.0637 | 5669141533 |
| 2000 | 0.5507 | 0.2415 | 0.0638 | 6085782447 |
| 2005 | 0.5531 | 0.2434 | 0.0681 | 6435695175 |
| 2010 | 0.5503 | 0.2474 | 0.0734 | 6830615581 |
# Evolución religiosa en América Latina
latam = df[df['name'].isin(paises_latam)]
evolucion_latam = latam.groupby('year').agg({
'chrstcatpct': 'mean', # Católicos
'chrstprotpct': 'mean', # Protestantes
'nonreligpct': 'mean' # Sin religión
}).round(4)
evolucion_latam.columns = ['Católicos %', 'Protestantes %', 'Sin Religión %']
print("Evolución religiosa en América Latina:")
evolucion_latam
Evolución religiosa en América Latina:
| Católicos % | Protestantes % | Sin Religión % | |
|---|---|---|---|
| year | |||
| 1945 | 0.8868 | 0.0143 | 0.0003 |
| 1950 | 0.8973 | 0.0145 | 0.0013 |
| 1955 | 0.9072 | 0.0122 | 0.0004 |
| 1960 | 0.9234 | 0.0131 | 0.0005 |
| 1965 | 0.9149 | 0.0136 | 0.0002 |
| 1970 | 0.9190 | 0.0195 | 0.0094 |
| 1975 | 0.9118 | 0.0218 | 0.0151 |
| 1980 | 0.9135 | 0.0248 | 0.0167 |
| 1985 | 0.9033 | 0.0264 | 0.0225 |
| 1990 | 0.8870 | 0.0357 | 0.0238 |
| 1995 | 0.8898 | 0.0438 | 0.0072 |
| 2000 | 0.8047 | 0.0924 | 0.0513 |
| 2005 | 0.7734 | 0.1036 | 0.0682 |
| 2010 | 0.7631 | 0.1222 | 0.0653 |
23.6. Tablas Dinámicas con pivot_table()#
Las tablas dinámicas permiten reorganizar datos para analizar relaciones entre variables.
# Tabla dinámica: Porcentaje de cristianos por país y año (América Latina)
pivot_latam = pd.pivot_table(
data=latam,
index='name', # Filas: países
columns='year', # Columnas: años
values='chrstgenpct', # Valores: % cristianos
aggfunc='mean' # Función de agregación
)
print("Porcentaje de cristianos en América Latina por año:")
(pivot_latam * 100).round(1) # Convertir a porcentaje
Porcentaje de cristianos en América Latina por año:
| year | 1945 | 1950 | 1955 | 1960 | 1965 | 1970 | 1975 | 1980 | 1985 | 1990 | 1995 | 2000 | 2005 | 2010 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| name | ||||||||||||||
| ARG | 98.4 | 94.4 | 91.0 | 95.2 | 96.1 | 96.9 | 96.0 | 94.0 | 92.5 | 90.6 | 92.0 | 89.9 | 84.5 | 85.2 |
| BOL | 89.8 | 96.0 | 99.8 | 94.5 | 94.5 | 95.0 | 98.2 | 98.8 | 97.2 | 95.4 | 98.5 | 94.2 | 95.8 | 94.3 |
| BRA | 99.2 | 95.0 | 91.6 | 97.7 | 95.6 | 98.6 | 98.8 | 98.7 | 97.8 | 95.4 | 97.2 | 86.1 | 85.8 | 88.2 |
| CHL | 92.0 | 91.2 | 94.4 | 98.2 | 93.7 | 94.0 | 93.2 | 94.0 | 93.7 | 94.3 | 95.6 | 93.3 | 87.8 | 91.3 |
| COL | 90.5 | 92.5 | 96.4 | 97.4 | 97.5 | 98.4 | 96.9 | 96.4 | 96.0 | 95.9 | 96.2 | 94.5 | 97.0 | 97.0 |
| ECU | 90.0 | 90.0 | 92.0 | 92.5 | 94.4 | 98.3 | 93.6 | 96.2 | 95.9 | 96.2 | 96.2 | 90.8 | 91.6 | 90.3 |
| MEX | 94.0 | 93.7 | 93.7 | 94.4 | 95.7 | 94.7 | 93.4 | 96.7 | 97.4 | 96.9 | 97.2 | 96.9 | 93.6 | 96.9 |
| PAR | 89.7 | 91.9 | 91.3 | 94.4 | 93.2 | 95.0 | 97.2 | 97.4 | 95.2 | 98.2 | 95.8 | 97.0 | 91.0 | 95.1 |
| PER | 93.0 | 96.2 | 93.0 | 96.3 | 96.1 | 98.6 | 96.0 | 98.4 | 97.5 | 99.0 | 99.0 | 91.7 | 96.0 | 93.8 |
| URU | 67.9 | 72.0 | 75.4 | 78.3 | 73.8 | 77.4 | 74.9 | 70.9 | 69.0 | 73.1 | 72.6 | 74.0 | 81.8 | 81.8 |
| VEN | 86.9 | 90.0 | 92.8 | 91.4 | 93.2 | 94.7 | 94.6 | 98.3 | 96.2 | 96.3 | 97.7 | 94.2 | 94.4 | 95.0 |
# Comparar católicos vs protestantes en América Latina (2010)
latam_2010_detalle = latam[latam['year'] == 2010][['name', 'chrstcatpct', 'chrstprotpct', 'pop']]
latam_2010_detalle['Católicos %'] = (latam_2010_detalle['chrstcatpct'] * 100).round(1)
latam_2010_detalle['Protestantes %'] = (latam_2010_detalle['chrstprotpct'] * 100).round(1)
latam_2010_detalle['Población (millones)'] = (latam_2010_detalle['pop'] / 1000000).round(1)
print("Católicos vs Protestantes en América Latina (2010):")
latam_2010_detalle[['name', 'Católicos %', 'Protestantes %', 'Población (millones)']].sort_values('Población (millones)', ascending=False)
Católicos vs Protestantes en América Latina (2010):
| name | Católicos % | Protestantes % | Población (millones) | |
|---|---|---|---|---|
| 342 | BRA | 59.6 | 26.8 | 190.8 |
| 164 | MEX | 82.7 | 14.1 | 112.3 |
| 269 | COL | 82.0 | 15.0 | 46.3 |
| 398 | ARG | 75.0 | 10.0 | 40.4 |
| 328 | PER | 81.3 | 12.5 | 29.4 |
| 283 | VEN | 80.0 | 15.0 | 28.8 |
| 384 | CHL | 75.9 | 10.6 | 17.1 |
| 314 | ECU | 87.0 | 2.0 | 14.2 |
| 356 | BOL | 80.9 | 13.3 | 10.3 |
| 370 | PAR | 88.0 | 4.0 | 6.5 |
| 412 | URU | 47.1 | 11.0 | 3.4 |
23.7. Manejo de Valores Faltantes#
Los datos reales a menudo tienen valores faltantes, representados como NaN (Not a Number).
# Verificar valores faltantes
print("Valores faltantes por columna:")
df[['year', 'name', 'pop', 'chrstgenpct', 'islmgenpct', 'nonreligpct']].isnull().sum()
Valores faltantes por columna:
year 0
name 0
pop 0
chrstgenpct 0
islmgenpct 0
nonreligpct 0
dtype: int64
# Verificar si hay filas con algún valor faltante en columnas clave
filas_con_nan = df[df['pop'].isnull()]
print(f"Filas con población faltante: {len(filas_con_nan)}")
Filas con población faltante: 0
# Eliminar filas con valores faltantes en una columna específica
df_limpio = df.dropna(subset=['pop'])
print(f"Filas originales: {len(df)}")
print(f"Filas después de limpiar: {len(df_limpio)}")
Filas originales: 1995
Filas después de limpiar: 1995
23.8. Creando Nuevas Columnas#
Podemos crear columnas calculadas a partir de datos existentes.
# Crear una copia para trabajar
df_analisis = df[df['year'] == 2010].copy()
# Crear columna: Población en millones
df_analisis['pop_millones'] = df_analisis['pop'] / 1000000
# Crear columna: Religión predominante
def religion_predominante(row):
religiones = {
'Cristiana': row['chrstgenpct'],
'Musulmana': row['islmgenpct'],
'Budista': row['budgenpct'],
'Hindú': row['hindgenpct']
}
return max(religiones, key=religiones.get)
df_analisis['religion_predominante'] = df_analisis.apply(religion_predominante, axis=1)
print("Países con su religión predominante (2010):")
df_analisis[['name', 'pop_millones', 'religion_predominante']].head(15)
Países con su religión predominante (2010):
| name | pop_millones | religion_predominante | |
|---|---|---|---|
| 13 | USA | 312.750000 | Cristiana |
| 27 | CAN | 34.500000 | Cristiana |
| 35 | BHM | 0.313312 | Cristiana |
| 49 | CUB | 11.241161 | Cristiana |
| 63 | HAI | 9.760832 | Cristiana |
| 77 | DOM | 9.956648 | Cristiana |
| 88 | JAM | 2.868630 | Cristiana |
| 99 | TRI | 1.305000 | Cristiana |
| 108 | BAR | 0.288705 | Cristiana |
| 115 | DMA | 0.073000 | Cristiana |
| 123 | GRN | 0.108419 | Cristiana |
| 130 | SLU | 0.164000 | Cristiana |
| 137 | SVG | 0.104000 | Cristiana |
| 144 | AAB | 0.086900 | Cristiana |
| 150 | SKN | 0.050700 | Cristiana |
# Contar países por religión predominante
print("Distribución de países por religión predominante (2010):")
df_analisis['religion_predominante'].value_counts()
Distribución de países por religión predominante (2010):
religion_predominante
Cristiana 129
Musulmana 49
Budista 13
Hindú 3
Name: count, dtype: int64
23.9. Ejercicio Práctico: Análisis Comparativo#
Ejercicio
Usando el dataset WRP National:
Compara la evolución del catolicismo en Chile vs México (1945-2010)
Encuentra los 5 países con mayor crecimiento de personas sin religión entre 1945 y 2010
Calcula el promedio de población musulmana por década
# Solución Ejercicio 1: Chile vs México - Catolicismo
chile_mex = df[df['name'].isin(['CHL', 'MEX'])][['year', 'name', 'chrstcatpct']]
pivot_comparacion = pd.pivot_table(
data=chile_mex,
index='year',
columns='name',
values='chrstcatpct'
)
print("Evolución del catolicismo: Chile vs México")
(pivot_comparacion * 100).round(1)
Evolución del catolicismo: Chile vs México
| name | CHL | MEX |
|---|---|---|
| year | ||
| 1945 | 88.8 | 93.0 |
| 1950 | 87.2 | 92.5 |
| 1955 | 90.8 | 92.5 |
| 1960 | 95.0 | 93.2 |
| 1965 | 88.0 | 94.1 |
| 1970 | 89.6 | 93.0 |
| 1975 | 88.9 | 91.6 |
| 1980 | 89.0 | 94.9 |
| 1985 | 84.8 | 95.7 |
| 1990 | 83.4 | 93.4 |
| 1995 | 82.0 | 93.9 |
| 2000 | 81.4 | 93.8 |
| 2005 | 70.0 | 89.7 |
| 2010 | 75.9 | 82.7 |
# Solución Ejercicio 2: Mayor crecimiento de "sin religión"
# Obtener datos de 1945 y 2010
sin_religion_1945 = df[df['year'] == 1945][['name', 'nonreligpct']].rename(columns={'nonreligpct': 'sin_rel_1945'})
sin_religion_2010 = df[df['year'] == 2010][['name', 'nonreligpct']].rename(columns={'nonreligpct': 'sin_rel_2010'})
# Unir los datasets
comparacion = pd.merge(sin_religion_1945, sin_religion_2010, on='name')
comparacion['cambio'] = comparacion['sin_rel_2010'] - comparacion['sin_rel_1945']
# Top 5 con mayor crecimiento
print("Top 5 países con mayor aumento de personas sin religión (1945-2010):")
top_cambio = comparacion.nlargest(5, 'cambio')
top_cambio['cambio_pct'] = (top_cambio['cambio'] * 100).round(1)
top_cambio[['name', 'cambio_pct']]
Top 5 países con mayor aumento de personas sin religión (1945-2010):
| name | cambio_pct | |
|---|---|---|
| 62 | NEW | 38.1 |
| 61 | AUL | 28.1 |
| 56 | CHN | 27.1 |
| 22 | UKG | 21.8 |
| 30 | GMY | 21.0 |
# Solución Ejercicio 3: Promedio de musulmanes por década
# Crear columna de década
df_decadas = df.copy()
df_decadas['decada'] = (df_decadas['year'] // 10) * 10
# Calcular promedio por década
musulmanes_decada = df_decadas.groupby('decada')['islmgenpct'].mean()
print("Porcentaje promedio de musulmanes por década:")
(musulmanes_decada * 100).round(2)
Porcentaje promedio de musulmanes por década:
decada
1940 14.59
1950 17.60
1960 22.38
1970 24.87
1980 23.98
1990 24.66
2000 24.24
2010 24.74
Name: islmgenpct, dtype: float64
23.10. Exportando Resultados#
Pandas permite guardar DataFrames en diversos formatos.
# Exportar a CSV
latam_2010_detalle[['name', 'Católicos %', 'Protestantes %', 'Población (millones)']].to_csv(
'analisis_latam_2010.csv',
index=False
)
print("Archivo exportado: analisis_latam_2010.csv")
Archivo exportado: analisis_latam_2010.csv
23.11. Resumen del Capítulo#
Operación |
Código |
Descripción |
|---|---|---|
Filtrar simple |
|
Una condición |
Filtrar múltiple |
|
AND: ambas condiciones |
Filtrar OR |
|
OR: al menos una |
Filtrar lista |
|
Valores en una lista |
Ordenar |
|
Ascendente por defecto |
Ordenar desc. |
|
Descendente |
Agrupar |
|
Calcular por grupo |
Múltiples stats |
|
Varias estadísticas |
Tabla dinámica |
|
Reorganizar datos |
Valores faltantes |
|
Contar NaN |
Eliminar NaN |
|
Quitar filas con NaN |
Nueva columna |
|
Columna calculada |
Exportar CSV |
|
Guardar resultados |