ML/AIMLE·AIMachine Learning Engineering
Ruta de aprendizaje · Nivel 2 de 10

Nivel 2 · Python para IA

El Python justo para empezar a trabajar con datos: las piezas básicas del lenguaje, NumPy para hacer cuentas con muchos números a la vez, Pandas para manejar tablas y Matplotlib para dibujarlas. Termina con tu primer análisis de datos reales.

Unas 5–7 horas · No hace falta instalar nada: todo funciona en Google Colab · Código de todos los ejemplos en notebooks/nivel2_python.py

01Cómo usar esta lección

Python es el idioma de la IA: casi todas las librerías de machine learning (scikit-learn, PyTorch, TensorFlow) se usan desde Python. No necesitas dominarlo entero; necesitas soltura con unas pocas piezas y cuatro herramientas.

PiezaPara qué sirveEn un proyecto de IA
Variables y tiposGuardar un dato con un nombreParámetros, rutas de archivos, resultados
Listas y diccionariosGuardar muchos datos juntosConfiguraciones, resultados de varios experimentos
Condiciones, bucles y funcionesDecidir, repetir y reutilizarLimpiar datos, entrenar varias veces, evaluar
NumPyHacer cuentas con muchos números a la vezLos datos de cualquier modelo son arrays de NumPy
PandasManejar tablasCargar, limpiar y explorar los datos
MatplotlibDibujar gráficosEntender los datos y los resultados

Antes de empezar: abre Google Colab

Google Colab es un cuaderno de Python en el navegador, gratis y sin instalar nada. Escribes código en una celda, pulsas Mayús + Intro y ves el resultado debajo. El botón «Abrir en Google Colab» del final de la lección carga todos los ejemplos.

¿Prefieres no salir de la web? El Laboratorio de Python ejecuta Python dentro del navegador, con 10 retos que se corrigen solos y errores explicados en español. Al final de cada apartado verás qué retos practicar.

El método es el del nivel 1: la idea en una frase, un ejemplo corto y dónde aparece en IA. Con una diferencia: aquí se aprende escribiendo. Teclea los ejemplos en vez de copiarlos, cambia los números y mira qué pasa. Equivocarse y leer el error es parte del aprendizaje.

021 · Variables y tipos

La idea en una fraseUna variable es un nombre que apunta a un dato.

Con = guardas un valor bajo un nombre para usarlo después. Cada dato tiene un tipo, y los cuatro básicos son estos:

Python
precio = 12.5          # float: número con decimales
unidades = 3           # int: número entero
producto = "vino"      # str: texto
en_oferta = True       # bool: verdadero o falso

total = precio * unidades
print(f"{unidades} × {producto} = {total} €")
Salida3 × vino = 37.5 €

La f delante de las comillas (una f-string) permite meter variables dentro del texto entre llaves. Es la forma más cómoda de mostrar resultados.

Operaciones con números

Python
7 / 2     # 3.5  división normal
7 // 2    # 3    división entera
7 % 2     # 1    resto
2 ** 3    # 8    potencia

Error típico: en Python los decimales se escriben con punto, no con coma: 12.5, nunca 12,5. Con coma, Python entiende dos números distintos.

Practica ahora: resuelve los retos 1 y 2 del Laboratorio de Python.

¿Dónde aparece en IA? la tasa de aprendizaje del nivel 1 se guarda así: eta = 0.1. Los hiperparámetros de un modelo son, sencillamente, variables.

032 · Listas y diccionarios

La idea en una fraseUna lista guarda datos en orden; un diccionario los guarda con nombre.

Listas: una fila de cajas numeradas

Python
notas = [7, 5, 9, 6]

len(notas)      # 4    cuántos elementos
sum(notas)      # 27
notas[0]        # 7    ¡el primero es el 0!
notas[-1]       # 6    el último
notas[1:3]      # [5, 9]  del 1 al 3, sin incluir el 3

notas.append(8)                  # añade al final
sum(notas) / len(notas)          # 7.0  la media

Error típico: los índices empiezan en 0, no en 1. El primer elemento es notas[0]. Y en notas[1:3] el 3 no se incluye.

Diccionarios: cajas con etiqueta

En vez de por posición, cada valor se busca por su nombre (su clave). Es perfecto para describir una cosa con varias propiedades:

Python
vino = {"alcohol": 9.4, "acidez": 0.70, "calidad": 5}

vino["alcohol"]        # 9.4
vino["calidad"] = 6    # cambiar un valor
vino.keys()            # los nombres: alcohol, acidez, calidad

Practica ahora: resuelve los retos 3 y 4 del Laboratorio de Python.

¿Dónde aparece en IA? una lista de resultados de cada época de entrenamiento, o un diccionario con la configuración del modelo: {"capas": 3, "eta": 0.01}.

043 · Condiciones y bucles

La idea en una fraseif decide qué hacer; for repite lo mismo para cada elemento.

Python
def etiqueta(calidad):
    if calidad >= 7:
        return "bueno"
    elif calidad >= 5:
        return "normal"
    else:
        return "malo"

for c in [4, 5, 7]:
    print(c, "→", etiqueta(c))
Salida4 → malo
5 → normal
7 → bueno

Fíjate en los dos puntos al final de cada if, elif, else y for, y en que lo de dentro va desplazado a la derecha (4 espacios). En Python esa sangría no es estética: es lo que dice qué líneas están dentro del bloque.

Error típico: mezclar la sangría o olvidar los dos puntos da IndentationError o SyntaxError. Otro clásico: usar = (guardar) en vez de == (comparar) dentro de un if.

Atajo muy usado: listas por comprensión

Crear una lista nueva a partir de otra en una línea. Se lee casi como en español: «n al cuadrado para cada n en…».

Python
[n ** 2 for n in range(5)]         # [0, 1, 4, 9, 16]
[n for n in notas if n >= 6]       # [7, 9, 6, 8]  solo las aprobadas

Practica ahora: resuelve los retos 5 y 7 del Laboratorio de Python. El 7 es un código con tres errores que tienes que arreglar.

¿Dónde aparece en IA? entrenar un modelo es un bucle: for epoca in range(100): calcula el error, calcula el gradiente, da un paso. Es el bucle del descenso de gradiente del nivel 1.

054 · Funciones

La idea en una fraseUna función es una receta con nombre: recibe datos, hace algo y devuelve un resultado.

Python
def media(valores):
    return sum(valores) / len(valores)

def precio_final(precio, descuento=0.0):     # descuento tiene valor por defecto
    return precio * (1 - descuento)

media([7, 5, 9, 6, 8])       # 7.0
precio_final(20)             # 20.0
precio_final(20, 0.25)       # 15.0

def crea la función, entre paréntesis van sus parámetros y return dice qué devuelve. Si un parámetro tiene valor por defecto (descuento=0.0) puedes no pasarlo.

Error típico: olvidar el return. La función se ejecuta, pero devuelve None y el error aparece más adelante, lejos de donde está el fallo.

Regla práctica: si copias el mismo código dos veces, conviértelo en una función.

Practica ahora: resuelve el reto 6 del Laboratorio de Python.

¿Dónde aparece en IA? en scikit-learn todo son funciones y métodos con parámetros por defecto: RandomForestClassifier(n_estimators=100). Leer su documentación es leer la lista de parámetros.

065 · NumPy: cuentas con muchos números a la vez

La idea en una fraseUn array de NumPy es una lista de números con la que puedes operar entera, sin bucles.

Con una lista normal, multiplicar todo por 2 exige un bucle. Con NumPy basta con x * 2: la operación se aplica a cada elemento. A esto se le llama vectorizar, y es la razón por la que los vectores del nivel 1 se programan tan fácil.

Python
import numpy as np

x = np.array([1.0, 2.0, 3.0, 4.0])

x * 2          # [2. 4. 6. 8.]     ¡sin bucle!
x + 10         # [11. 12. 13. 14.]
x ** 2         # [1. 4. 9. 16.]
x.mean()       # 2.5
x.max()        # 4.0

x > 2          # [False False True True]
x[x > 2]       # [3. 4.]   filtrar con una condición

u, v = np.array([3, 1]), np.array([1, 2])
u @ v          # 5   el producto escalar del nivel 1

La línea x[x > 2] es muy útil: la condición crea una lista de True/False (una máscara) y con ella te quedas solo con los elementos que la cumplen.

¿Por qué no usar bucles? Por velocidad

Sumar los cuadrados de un millón de números de las dos formas:

Python
datos = list(range(1_000_000))
arr = np.arange(1_000_000, dtype=float)

# Con un bucle de Python
total = 0
for d in datos:
    total += d * d

# Con NumPy: una sola línea
total = (arr * arr).sum()
Bucle de Python27 ms
NumPy1,6 ms
Tiempo medido en nuestra prueba (el mejor de 5 intentos). NumPy fue unas 16 veces más rápido; la cifra exacta cambia según el ordenador, pero la diferencia siempre es grande.

Practica ahora: resuelve el reto 8 del Laboratorio de Python.

¿Dónde aparece en IA? un lote de 32 imágenes de 28 × 28 píxeles es un array de forma (32, 784), y una capa de red neuronal es X @ W. PyTorch y TensorFlow funcionan con la misma idea y casi la misma sintaxis que NumPy.

076 · Pandas: tablas

La idea en una fraseUn DataFrame de Pandas es una hoja de cálculo que manejas con código.

Imagina este archivo ventas.csv, con dos huecos (datos que faltan):

tiendamesventas
Centroene120
Centrofebvacío
Playaene80
Playafeb95
Puertoenevacío
Puertofeb60

Paso 1 · Cargar y mirar

Python
import pandas as pd

df = pd.read_csv("ventas.csv")

df.shape                  # (6, 3): 6 filas y 3 columnas
df.head()                 # las primeras filas
df["ventas"]              # una columna
df.isna().sum()           # cuántos nulos hay en cada columna → ventas: 2

Las casillas vacías aparecen como NaN («no es un número»). Siempre hay que buscarlas antes de hacer nada más.

Paso 2 · Limpiar los nulos

Python
df["ventas"].mean()                  # 88.75  (Pandas ignora los nulos)

df.dropna()                          # opción A: quitar filas con nulos → quedan 4
mediana = df["ventas"].median()      # 87.5
df = df.fillna({"ventas": mediana})  # opción B: rellenarlos con la mediana

¿Quitar o rellenar? Si faltan pocas filas, quitarlas es lo más sencillo. Si son muchas, perderías demasiados datos, y es mejor rellenar con un valor razonable, como la mediana.

Paso 3 · Agrupar y filtrar

groupby es la herramienta estrella: «para cada tienda, suma sus ventas». Es como una tabla dinámica de Excel en una línea.

Python
df.groupby("tienda")["ventas"].sum()
# Centro    207.5
# Playa     175.0
# Puerto    147.5

df[df["ventas"] > 90]      # filtrar filas: solo las que venden más de 90

Error típico: un CSV no siempre separa con comas. Si al cargarlo te sale una sola columna con todo junto, prueba pd.read_csv(archivo, sep=";"). Te pasará en el proyecto.

Practica ahora: resuelve los retos 9 y 10 del Laboratorio de Python.

¿Dónde aparece en IA? el 80 % del trabajo real en machine learning es esto: cargar, limpiar y entender los datos antes de entrenar nada. Un modelo entrenado con datos sucios da resultados sucios.

087 · Matplotlib: gráficos

La idea en una fraseUn gráfico te enseña en un segundo lo que una tabla esconde.

Con tres tipos de gráfico cubres casi todo al empezar:

GráficoPregunta que respondeCódigo
Histograma¿Cómo se reparten los valores de una columna?plt.hist(col)
Dispersión¿Hay relación entre dos columnas?plt.scatter(x, y)
Barras¿Cuánto hay de cada categoría?plt.bar(nombres, valores)
Python
import matplotlib.pyplot as plt

plt.hist(vinos["alcohol"], bins=20)        # histograma: cómo se reparten los valores
plt.title("Grado de alcohol de los vinos")
plt.xlabel("alcohol (%)"); plt.ylabel("número de vinos")
plt.show()

plt.scatter(vinos["alcohol"], vinos["quality"], s=8)   # dispersión: relación entre dos columnas
plt.xlabel("alcohol (%)"); plt.ylabel("calidad")
plt.show()

Error típico: un gráfico sin título ni nombres en los ejes no sirve para nada una semana después. Ponlos siempre.

¿Dónde aparece en IA? la curva de aprendizaje (el error en cada época) es un gráfico de líneas, y con ella se detecta el sobreajuste. Lo verás en el laboratorio de sobreajuste.

09Ejercicios

Escríbelos en Colab (o en la zona libre del Laboratorio de Python) antes de abrir la solución. Si algo da error, lee el mensaje: casi siempre dice la línea y el motivo.

Ejercicio 1¿Qué muestra print(f"{2 + 3} manzanas")? ¿Y 10 // 3 y 10 % 3?
Solución

5 manzanas. 10 // 3 es 3 (división entera) y 10 % 3 es 1 (el resto).

Ejercicio 2Con edades = [23, 35, 18, 42, 29], obtén el primer y el último elemento, los tres primeros y la media.

Pista: la media es la suma entre el número de elementos.

Solución

edades[0] → 23, edades[-1] → 29, edades[:3] → [23, 35, 18], sum(edades) / len(edades) → 29.4.

Ejercicio 3Escribe una función es_par(n) que devuelva True si n es par. Úsala para quedarte solo con los pares de range(10).

Pista: un número es par si el resto de dividir entre 2 es 0.

Solución
def es_par(n):
    return n % 2 == 0

[n for n in range(10) if es_par(n)]   # [0, 2, 4, 6, 8]
Ejercicio 4Con NumPy y sin bucles: dado t = np.array([12, 18, 25, 31, 9]) (temperaturas en °C), pásalas a Fahrenheit (F = C · 1,8 + 32) y quédate con las mayores de 20 °C.
Solución
t * 1.8 + 32     # [53.6 64.4 77.  87.8 48.2]
t[t > 20]        # [25 31]
Ejercicio 5El ejercicio del nivel. Carga el ventas.csv de la lección, cuenta los nulos, rellénalos con la mediana y calcula las ventas totales por tienda.

Pista: si no tienes el archivo, créalo en Colab con el código del cuaderno de la lección.

Solución

df.isna().sum() da 2 nulos en ventas. La mediana es 87,5. Tras fillna, df.groupby("tienda")["ventas"].sum() da Centro 207,5, Playa 175 y Puerto 147,5.

Ejercicio 6Este código da error. ¿Por qué?
def doble(x)
    return x * 2
Solución

Faltan los dos puntos después de def doble(x). Python responde SyntaxError: expected ':'.

10Proyecto: tu primer análisis de datos reales

Vas a explorar Wine Quality: 1.599 vinos tintos portugueses con 11 medidas químicas cada uno y una nota de calidad del 0 al 10 que pusieron catadores expertos. La pregunta: ¿qué tienen en común los vinos buenos?

Solución de referencia
import pandas as pd
import matplotlib.pyplot as plt

URL = "https://raw.githubusercontent.com/vtarazona/mle-ai/main/notebooks/data/winequality-red.csv"
vinos = pd.read_csv(URL, sep=";")          # ¡este CSV separa con punto y coma!

# 1. Primer vistazo
print(vinos.shape)                          # (1599, 12)
print(vinos.head())
print(vinos.isna().sum().sum())             # 0 nulos
print(vinos.duplicated().sum())             # 240 filas repetidas

# 2. ¿Cómo se reparte la calidad?
print(vinos["quality"].value_counts().sort_index())

# 3. ¿Qué tienen en común los vinos buenos?
print(vinos.groupby("quality")["alcohol"].mean().round(2))
print(vinos.corr()["quality"].sort_values().round(3))

# 4. Gráficos
fig, ax = plt.subplots(1, 3, figsize=(15, 4))
vinos["quality"].value_counts().sort_index().plot.bar(ax=ax[0], title="Vinos por calidad")
vinos.boxplot(column="alcohol", by="quality", ax=ax[1])
ax[2].scatter(vinos["alcohol"], vinos["volatile acidity"], c=vinos["quality"], s=8)
ax[2].set_xlabel("alcohol (%)"); ax[2].set_ylabel("acidez volátil")
plt.tight_layout(); plt.show()

Lo que deberías encontrar

1. Los datos están limpios, pero no del todo. Hay 1.599 filas y 12 columnas, sin nulos. Sin embargo, 240 filas están repetidas: conviene saberlo, porque inflan algunos resultados.

2. La calidad está muy concentrada. Casi todos los vinos son de 5 o 6. Los excelentes (7 u 8) son solo 217, un 13,6 %.

Calidad 310
Calidad 453
Calidad 5681
Calidad 6638
Calidad 7199
Calidad 818
Número de vinos de cada calidad. Si algún día entrenas un modelo con estos datos, esta desigualdad importará: le costará aprender los extremos.

3. Más alcohol, mejor nota. La media de alcohol sube casi siempre con la calidad: 9,90 % en los de calidad 5, 10,63 % en los de 6, 11,47 % en los de 7 y 12,09 % en los de 8.

4. Las dos pistas más fuertes. La correlación es un número entre −1 y 1 que dice si dos columnas suben juntas (positiva) o una sube cuando la otra baja (negativa):

alcohol+0,48
sulfatos+0,25
ácido cítrico+0,23
azúcar residual+0,01
densidad−0,17
dióxido de azufre total−0,18
acidez volátil−0,39
Correlación de algunas medidas químicas con la calidad. El alcohol va a favor y la acidez volátil (el sabor avinagrado) en contra.

Error típico: correlación no es causa. Que los vinos buenos tengan más alcohol no significa que añadir alcohol mejore un vino. Lo verás en el nivel 3.

Para ir más allá: (1) quita los duplicados con vinos.drop_duplicates() y comprueba si cambian las conclusiones; (2) haz lo mismo con los vinos blancos (winequality-white.csv); (3) escribe en tres frases, para alguien que no sabe de datos, qué has descubierto.

11Test de autoevaluación

  1. ¿Qué tipo de dato es 3.0?

  2. Con notas = [7, 5, 9, 6], ¿qué da notas[1]?

  3. ¿Cuándo es mejor un diccionario que una lista?

  4. ¿Qué indica en Python qué líneas están dentro de un if o un for?

  5. Una función no tiene return. ¿Qué devuelve?

  6. Con x = np.array([1, 2, 3]), ¿qué da x * 2?

  7. ¿Por qué se usa NumPy en vez de bucles para operar con muchos números?

  8. ¿Qué hace df.isna().sum()?

  9. Quieres la media de ventas de cada tienda. ¿Qué usas?

  10. Cargas un CSV y te sale una sola columna con todo el texto junto. ¿Qué es lo más probable?

12¿Has asimilado el nivel?

Marca cada punto solo si puedes hacerlo sin mirar la lección (buscar en Google la sintaxis exacta sí vale: los profesionales lo hacen a diario). El progreso se guarda solo en este navegador.

Para practicar más

  1. Documentación oficial de Python en español: El tutorial de Python (docs.python.org/es), capítulos 3 a 5.
  2. Pandas: 10 minutes to pandas, la guía rápida oficial.
  3. J. VanderPlas (2023). Python Data Science Handbook, 2.ª ed. O'Reilly. Gratis en la web del autor; capítulos de NumPy, Pandas y Matplotlib.
  4. P. Cortez et al. (2009). Modeling wine preferences by data mining from physicochemical properties. Decision Support Systems, 47(4). Origen del dataset Wine Quality (UCI, licencia CC BY 4.0).

Ejecuta el código de la lección

Todos los ejemplos, los ejercicios y el proyecto, con los datos incluidos:

Anterior: Nivel 1 · Matemáticas · Siguiente: Nivel 3 · Estadística · Volver a la ruta