Clase 2 — Listas, funciones y numpy#
Python y Políticas Públicas
Contenidos#
Listas: creación, indexing y operaciones
Diccionarios
Funciones
Introducción a numpy
Ejercicio integrador
1. Listas#
Una lista es una colección ordenada y mutable de elementos. Es una de las estructuras de datos más usadas en Python.
# Crear listas
provincias = ["Buenos Aires", "Córdoba", "Santa Fe", "Mendoza", "Tucumán"]
tasas_desempleo = [8.2, 7.5, 9.1, 6.8, 11.3] # % por provincia
datos_mixtos = ["Buenos Aires", 8.2, True, 2023] # se pueden mezclar tipos
print(provincias)
print(f"Cantidad de provincias: {len(provincias)}")
['Buenos Aires', 'Córdoba', 'Santa Fe', 'Mendoza', 'Tucumán']
Cantidad de provincias: 5
import matplotlib as mpl
import matplotlib.pyplot as plt
# --- Paleta de identidad del curso ---
C = ['#2A6496', '#E07B3F', '#3D9970', '#8E5EA2', '#C0A830', '#637A8A']
mpl.rcParams.update({
'figure.figsize' : (10, 5),
'font.size' : 11,
'axes.titlesize' : 12,
'axes.titleweight' : 'normal',
'axes.spines.top' : False,
'axes.spines.right' : False,
'legend.frameon' : False,
'axes.prop_cycle' : mpl.cycler(color=C),
'figure.dpi' : 110,
})
def tit(ax, t, **kw):
"""Título sin negrita, alineado a la izquierda."""
ax.set_title(t, loc='left', fontweight='normal', **kw)
# Indexing: acceder a elementos por posición (empieza en 0)
print(provincias[0]) # primer elemento
print(provincias[-1]) # último elemento
print(provincias[1:3]) # slicing: elementos 1 y 2 (no incluye el 3)
print(provincias[:2]) # primeros dos
print(provincias[2:]) # desde el tercero hasta el final
Buenos Aires
Tucumán
['Córdoba', 'Santa Fe']
['Buenos Aires', 'Córdoba']
['Santa Fe', 'Mendoza', 'Tucumán']
# Operaciones sobre listas
tasas = [8.2, 7.5, 9.1, 6.8, 11.3]
tasas.append(10.2) # agregar al final
tasas.insert(0, 5.5) # insertar en posición 0
tasas.remove(9.1) # eliminar primer elemento con ese valor
tasas.sort() # ordenar (modifica la lista)
print(tasas)
print(f"Mínimo: {min(tasas)}, Máximo: {max(tasas)}, Suma: {sum(tasas):.1f}")
[5.5, 6.8, 7.5, 8.2, 10.2, 11.3]
Mínimo: 5.5, Máximo: 11.3, Suma: 49.5
2. Diccionarios#
Un diccionario almacena pares clave: valor. Es ideal para representar registros o filas de datos.
# Un programa social como diccionario
programa = {
"nombre": "Asignación Universal por Hijo",
"organismo": "ANSES",
"beneficiarios": 4_200_000,
"monto_mensual": 42_000,
"activo": True
}
# Acceder a valores
print(programa["nombre"])
print(programa.get("beneficiarios", 0)) # get() no falla si la clave no existe
# Modificar y agregar
programa["monto_mensual"] = 48_000
programa["anio_inicio"] = 2009
# Iterar
for clave, valor in programa.items():
print(f" {clave}: {valor}")
Asignación Universal por Hijo
4200000
nombre: Asignación Universal por Hijo
organismo: ANSES
beneficiarios: 4200000
monto_mensual: 48000
activo: True
anio_inicio: 2009
# Lista de diccionarios: estructura muy común para tablas de datos
programas = [
{"nombre": "AUH", "beneficiarios": 4_200_000, "organismo": "ANSES"},
{"nombre": "Progresar", "beneficiarios": 1_100_000, "organismo": "ANSES"},
{"nombre": "Potenciar", "beneficiarios": 1_300_000, "organismo": "MDS"},
]
total_beneficiarios = sum(p["beneficiarios"] for p in programas)
print(f"Total de beneficiarios: {total_beneficiarios:,}")
# Filtrar programas de ANSES
anses = [p["nombre"] for p in programas if p["organismo"] == "ANSES"]
print(f"Programas de ANSES: {anses}")
Total de beneficiarios: 6,600,000
Programas de ANSES: ['AUH', 'Progresar']
3. Funciones#
Una función es un bloque de código reutilizable que realiza una tarea específica. Usar funciones hace el código más limpio, modular y fácil de mantener.
# Definición básica
def calcular_tasa_cobertura(poblacion_total, poblacion_cubierta):
"""Devuelve la tasa de cobertura en porcentaje."""
return (poblacion_cubierta / poblacion_total) * 100
# Uso
tasa = calcular_tasa_cobertura(8_500_000, 7_820_000)
print(f"Tasa de cobertura: {tasa:.1f}%")
Tasa de cobertura: 92.0%
# Argumentos por defecto
def clasificar_tasa(tasa, umbral_alto=80, umbral_medio=60):
"""Clasifica una tasa según umbrales configurables."""
if tasa >= umbral_alto:
return "alta"
elif tasa >= umbral_medio:
return "media"
else:
return "baja"
print(clasificar_tasa(92.0)) # usa umbrales por defecto
print(clasificar_tasa(65.0, umbral_alto=90, umbral_medio=70)) # umbrales custom
alta
baja
# Devolver múltiples valores
def estadisticas_basicas(lista):
"""Devuelve media, mínimo y máximo de una lista."""
media = sum(lista) / len(lista)
return media, min(lista), max(lista)
tasas = [8.2, 7.5, 9.1, 6.8, 11.3, 10.2]
media, minimo, maximo = estadisticas_basicas(tasas)
print(f"Media: {media:.2f} | Mínimo: {minimo} | Máximo: {maximo}")
Media: 8.85 | Mínimo: 6.8 | Máximo: 11.3
4. Introducción a numpy#
numpy es la librería fundamental para cómputo numérico en Python. Sus arrays son mucho más eficientes que las listas de Python para operaciones matemáticas.
import numpy as np # convención: importar como np
# Crear arrays
tasas = np.array([8.2, 7.5, 9.1, 6.8, 11.3, 10.2, 8.9, 7.1])
print(f"Array: {tasas}")
print(f"Tipo: {tasas.dtype}")
print(f"Forma: {tasas.shape}")
print(f"Longitud: {len(tasas)}")
Array: [ 8.2 7.5 9.1 6.8 11.3 10.2 8.9 7.1]
Tipo: float64
Forma: (8,)
Longitud: 8
# Operaciones vectorizadas (se aplican a todos los elementos a la vez)
tasas = np.array([8.2, 7.5, 9.1, 6.8, 11.3, 10.2, 8.9, 7.1])
# Estadísticas
print(f"Media: {tasas.mean():.2f}")
print(f"Mediana: {np.median(tasas):.2f}")
print(f"Desvío: {tasas.std():.2f}")
print(f"Mínimo: {tasas.min()}")
print(f"Máximo: {tasas.max()}")
# Operaciones aritméticas sobre todo el array
tasas_decimal = tasas / 100
print(f"\nEn decimal: {tasas_decimal}")
Media: 8.64
Mediana: 8.55
Desvío: 1.46
Mínimo: 6.8
Máximo: 11.3
En decimal: [0.082 0.075 0.091 0.068 0.113 0.102 0.089 0.071]
# Filtrado con condiciones booleanas
tasas = np.array([8.2, 7.5, 9.1, 6.8, 11.3, 10.2, 8.9, 7.1])
altas = tasas[tasas > 9] # tasas mayores a 9%
print(f"Tasas altas (> 9%): {altas}")
print(f"Cantidad: {len(altas)} de {len(tasas)} regiones")
Tasas altas (> 9%): [ 9.1 11.3 10.2]
Cantidad: 3 de 8 regiones
# Arrays 2D: como una tabla/matriz
# Filas = años (2021, 2022, 2023), Columnas = regiones (NOA, NEA, Centro, Cuyo, Patagonia)
desempleo = np.array([
[10.1, 11.5, 8.3, 7.2, 6.8], # 2021
[ 9.8, 10.9, 7.9, 6.5, 6.1], # 2022
[ 9.2, 10.2, 7.5, 6.8, 5.9], # 2023
])
print(f"Forma: {desempleo.shape}") # (3 filas, 5 columnas)
print(f"Media por región: {desempleo.mean(axis=0).round(2)}") # a lo largo de filas
print(f"Media por año: {desempleo.mean(axis=1).round(2)}") # a lo largo de columnas
Forma: (3, 5)
Media por región: [ 9.7 10.87 7.9 6.83 6.27]
Media por año: [8.78 8.24 7.92]
5. Ejercicio integrador#
Combinamos funciones, numpy, listas y for.
Contexto: Tenés datos de pobreza para 6 provincias en tres años consecutivos. Querés:
Calcular la variación interanual de la tasa de pobreza para cada provincia.
Identificar qué provincias mejoraron (tasa bajó) y cuáles empeoraron.
Calcular el promedio nacional de mejora/deterioro.
import numpy as np
provincias = ["Buenos Aires", "Córdoba", "Santa Fe", "Mendoza", "Tucumán", "Salta"]
# Tasas de pobreza (%) por año
pobreza_2021 = np.array([42.3, 38.1, 39.7, 34.2, 48.6, 52.1])
pobreza_2022 = np.array([40.1, 36.8, 38.2, 33.5, 46.9, 50.7])
pobreza_2023 = np.array([38.9, 35.4, 37.1, 32.8, 45.2, 49.3])
def calcular_variacion(tasa_anterior, tasa_actual):
"""Devuelve la variación en puntos porcentuales (negativo = mejora)."""
return tasa_actual - tasa_anterior
# Variaciones
var_21_22 = calcular_variacion(pobreza_2021, pobreza_2022)
var_22_23 = calcular_variacion(pobreza_2022, pobreza_2023)
print("=" * 60)
print(f"{'Provincia':<20} {'2021':>6} {'2022':>6} {'2023':>6} {'Var 21-22':>10} {'Tendencia':>12}")
print("-" * 60)
for i, provincia in enumerate(provincias):
variacion = var_22_23[i]
tendencia = "↓ mejora" if variacion < 0 else "↑ empeora"
print(f"{provincia:<20} {pobreza_2021[i]:>6.1f} {pobreza_2022[i]:>6.1f} {pobreza_2023[i]:>6.1f} {variacion:>+10.1f} {tendencia:>12}")
print("-" * 60)
print(f"Variación promedio 2022-2023: {var_22_23.mean():+.2f} pp")
print(f"Provincias que mejoraron: {(var_22_23 < 0).sum()} de {len(provincias)}")
============================================================
Provincia 2021 2022 2023 Var 21-22 Tendencia
------------------------------------------------------------
Buenos Aires 42.3 40.1 38.9 -1.2 ↓ mejora
Córdoba 38.1 36.8 35.4 -1.4 ↓ mejora
Santa Fe 39.7 38.2 37.1 -1.1 ↓ mejora
Mendoza 34.2 33.5 32.8 -0.7 ↓ mejora
Tucumán 48.6 46.9 45.2 -1.7 ↓ mejora
Salta 52.1 50.7 49.3 -1.4 ↓ mejora
------------------------------------------------------------
Variación promedio 2022-2023: -1.25 pp
Provincias que mejoraron: 6 de 6
Ejercicios#
Ejercicio 1#
Creá una función indice_desarrollo(salud, educacion, ingresos) que calcule el promedio de los tres parámetros (todos en escala 0-100). Aplicala a las siguientes regiones usando un for:
regiones = [
{"nombre": "NOA", "salud": 62, "educacion": 58, "ingresos": 45},
{"nombre": "NEA", "salud": 60, "educacion": 55, "ingresos": 42},
{"nombre": "Centro", "salud": 78, "educacion": 80, "ingresos": 75},
{"nombre": "Cuyo", "salud": 72, "educacion": 70, "ingresos": 65},
{"nombre": "Patagonia", "salud": 80, "educacion": 77, "ingresos": 82},
]
Imprimí el índice de cada región y al final la región con el índice más alto.
# Tu solución aquí
Ejercicio 2#
Usá numpy para analizar la siguiente serie de presupuesto ejecutado mensualmente (en millones de pesos) durante un año:
ejecucion = np.array([820, 910, 880, 1050, 970, 1200, 1180, 1150, 1300, 1250, 1400, 1350])
Calculá: media, mediana, desvío estándar, y el porcentaje de meses que superaron la media.
import numpy as np
ejecucion = np.array([820, 910, 880, 1050, 970, 1200, 1180, 1150, 1300, 1250, 1400, 1350])
# Tu solución aquí