Saltar al contenido
Volver al inicio 100 Días de Código en Python — Día 74: Agregar y combinar datos con pandas — la historia de LEGO

100 Días de Código en Python — Día 74: Agregar y combinar datos con pandas — la historia de LEGO

Nivel: Grado décimo Área: Tecnología e Informática Modalidad: Tutorial práctico Fuente: Curso "100 Days of Code: The Complete Python Pro Bootcamp" (Angela Yu, App Brewery). Contenido del Día 74 (nivel avanzado).

Este tutorial adapta pedagógicamente el Día 74. Las secciones 📝 Contenido original del curso provienen de las lecciones 539 a 549; el cuaderno de inicio, las imágenes y los datos (colors.csv, sets.csv, themes.csv) están en los recursos del curso. En varias lecciones el código aparece solo en imágenes; aquí se reconstruye y se verifica. Los retos 🟢🟡🟠🔴, la actualización con datos de 2026, el proyecto extra y la etapa 3 del proyecto integrador son creaciones de esta adaptación. Las correcciones al material original aparecen como 🛠️ Nota técnica.

Nota sobre las verificaciones: el 27 de septiembre de 2026, con Python 3.14, pandas 3.0.6, Matplotlib 3.11.2 y una copia pública de los CSV del curso (publicada en GitHub por otro estudiante del mismo curso), se ejecutó todo el código. Todos los resultados coinciden con los del curso: 135 colores, 5 sets en 1949, 840 sets en 2019, el tema 158 con 753 sets, 4 temas llamados "Star Wars", etc. También se descargaron los datos actuales de la fuente original, Rebrickable (cdn.rebrickable.com): 28 401 sets, con años de 1949 a 2027 y una columna nueva, img_url.


Tabla de contenidos

  1. Antes de empezar: preguntas sobre LEGO
  2. Markdown y HTML en el cuaderno; los colores de LEGO
  3. Los sets más antiguos y más grandes
  4. Sets por año y rebanadas
  5. La función .agg(): temas por año
  6. Dos ejes en un gráfico
  7. Gráficos de dispersión: piezas por set
  8. Esquemas relacionales: claves primarias y foráneas
  9. Combinar DataFrames y gráficos de barras
  10. 📖 Los datos cambian: LEGO en 2026
  11. 🚀 Proyecto del día: el informe de la historia de LEGO
  12. 🌟 Proyecto extra: la biblioteca del colegio en tablas relacionadas
  13. 🏗️ Proyecto integrador del bloque de datos — Etapa 3
  14. 🧩 Comprueba lo aprendido
  15. 🤖 Programar con apoyo de IA
  16. 🛠️ Correcciones técnicas al material original
  17. 📋 Matriz de trazabilidad
  18. 📦 Evidencias de aprendizaje del Día 74

0. Antes de empezar: preguntas sobre LEGO

(Fuente: 539-day-74-goals-what-you-will-make-by-the-end-of-the-day.md)

📝 Contenido original del curso

Un conjunto de datos sobre LEGO para responder:

  • ¿Cuál es el set más enorme jamás creado y cuántas piezas tenía?
  • ¿En qué año salieron los primeros sets y cuántos vendía la empresa al comienzo?
  • ¿Qué tema tiene más sets: Harry Potter, Ninjago, Friends u otro?
  • ¿Cuándo "despegó" la empresa según su oferta? ¿Cuántos temas y sets lanzaba cada año?
  • ¿Los sets crecieron en tamaño y complejidad con el tiempo?

Aprenderás a combinar un cuaderno con HTML, a usar rebanadas de listas en DataFrames, a agregar datos con .agg(), a hacer gráficos de dispersión, de barras y de líneas con dos ejes, a entender esquemas de bases de datos con claves primarias y foráneas, y a combinar DataFrames que comparten una clave.

Preparación: descarga el ZIP (cuaderno, imágenes y datos), sube el cuaderno a Google Drive y crea en Colab una carpeta data con los CSV (no se pueden arrastrar carpetas enteras). La carpeta de imágenes solo hace falta en Jupyter.

Prerequisitos: pandas con groupby, sort_values y gráficos de líneas (Días 72 y 73), rebanadas de listas (Día 21), HTML (Días 41 a 44), claves primarias y foráneas (Días 63 y 69).


1. Markdown y HTML en el cuaderno; los colores de LEGO

(Fuentes: 540-use-html-markdown-to-make-your-notebook-look-pretty.md, 541-solution-exploring-the-lego-brick-colours.md y 542, primera parte)

📝 Contenido original del curso

Las celdas pueden ser de código o de texto (Markdown). En las de texto se puede usar HTML:

  • Imágenes: <img src="https://i.imgur.com/49FNOHj.jpg"> (en Jupyter también <img src="assets/bricks.jpg">).
  • Títulos: <h1>, <h2>… o el atajo de Markdown #, ##… (hasta el nivel 5). Texto en negrita: **así**.

Reto: ¿cuántos colores distintos de ladrillos LEGO hay? Lee data/colors.csv y usa .nunique(). ¿Cuántos son transparentes y cuántos opacos? Encuentra al menos dos formas.

Solución:

Python
import pandas as pd

colors = pd.read_csv('data/colors.csv')
colors.head()
colors['name'].nunique()                 # 135 colores únicos

colors.groupby('is_trans').count()       # forma 1
colors.is_trans.value_counts()           # forma 2: más rápida

📖 Resultados verificados

colors.csv tiene 4 columnas (id, name, rgb, is_trans) y 135 filas; los 135 nombres son únicos. Transparentes (t): 28; opacos (f): 107.

💡 is_trans usa 't' y 'f' (texto), no True/False. Para trabajar con booleanos: colors['is_trans'] = colors['is_trans'] == 't'.

Retos adicionales (creados para esta adaptación)

  • 🟢 Reto 1: muestra los 10 primeros colores con su nombre y su código RGB.
  • 🟡 Reto 2: en una celda de Markdown, dibuja una tabla HTML con 5 colores y el fondo de cada celda del color correspondiente (<td style="background:#...">).
  • 🟠 Reto 3: con la función de contraste del Día 65, calcula qué colores de LEGO se leerían bien como texto sobre fondo blanco.

2. Los sets más antiguos y más grandes

(Fuente: 542-find-the-oldest-and-largest-lego-sets.md)

📝 Contenido original del curso

sets.csv lista los sets de LEGO con: set_num (identificador), name, year, theme_id (código del tema) y num_parts.

  • ¿En qué año salieron los primeros sets y cómo se llamaban? → ordenar por year (ascendente por defecto).
  • ¿Cuántos productos vendía LEGO el primer año? → filtrar: sets[sets['year'] == 1949].
  • ¿Cuáles son los 5 sets con más piezas? → ordenar por num_parts con ascending=False.

LEGO empezó en 1949 con solo 5 sets. El set más grande tiene cerca de 10 000 piezas y "solo se fabricaron dos cajas"; la alternativa es el Millennium Falcon de 7541 piezas.

📖 Resultados verificados

Python
sets = pd.read_csv('data/sets.csv')          # 15 710 filas, 5 columnas
sets.sort_values('year').head()
sets[sets['year'] == 1949]                   # 5 filas
sets.sort_values('num_parts', ascending=False).head()
Set más grande (datos del curso) Año Piezas
The Ultimate Battle for Chima 2015 9987
UCS Millennium Falcon 2017 7541
Hogwarts Castle 2018 6020
Taj Mahal 2017 5923
Taj Mahal 2008 5922

Filtrar, paso a paso: sets['year'] == 1949 produce una columna de True/False (una "máscara"); sets[máscara] se queda con las filas True. Se pueden combinar condiciones con & (y) y | (o), con paréntesis: sets[(sets.year >= 2000) & (sets.num_parts > 1000)].


3. Sets por año y rebanadas

(Fuente: 543-visualise-the-number-of-sets-published-over-time.md)

🎯 Objetivo de aprendizaje

Contar registros por año, graficarlos y excluir años incompletos con rebanadas.

📝 Contenido original del curso

Reto: una serie sets_by_year con el año como índice y el número de sets como valor, y su gráfico de líneas. Como el CSV es de finales de 2020, hay que excluir los últimos años con rebanadas (Día 21).

Solución: agrupar por año y contar.

Python
sets_by_year = sets.groupby('year').count()
plt.plot(sets_by_year.index, sets_by_year.set_num)            # termina con una caída engañosa
plt.plot(sets_by_year.index[:-2], sets_by_year.set_num[:-2])  # sin 2020 ni 2021

LEGO publicó menos de 10 sets al año al comienzo; en 2019, 840. Hay datos de 2021 porque el archivo incluye sets anunciados. Sin excluir los dos últimos años, el gráfico sugiere que "LEGO está en problemas", lo cual es engañoso. Se ve un crecimiento sostenido los primeros 45 años, un gran aumento a mediados de los 90, una caída a comienzos de los 2000 y una recuperación hacia 2005.

📖 Explicación conceptual (verificada)

Últimos años de los datos del curso: 2018 → 816, 2019 → 840, 2020 → 674 (año incompleto), 2021 → 3 (solo anuncios). Por eso [:-2].

🛠️ Nota técnica: [:-2] depende de que los dos últimos años sean justamente los incompletos. Es más robusto filtrar por valor: sets_by_year.loc[:2019]. Si usas datos más recientes (sección 9), la rebanada [:-2] excluiría los años equivocados; el filtro por año sigue funcionando.

Una lección de visualización: un gráfico puede mentir sin querer si incluye periodos incompletos. Siempre pregúntate si el último punto está completo.


4. La función .agg(): temas por año

(Fuente: 544-how-to-use-the-pandas-agg-function.md)

📝 Contenido original del curso

.agg() permite aplicar operaciones específicas a columnas específicas después de agrupar. Para contar los temas distintos por año:

Python
themes_by_year = sets.groupby('year').agg({'theme_id': pd.Series.nunique})
themes_by_year.rename(columns={'theme_id': 'nr_themes'}, inplace=True)

.agg() recibe un diccionario: columna → operación. Al comienzo LEGO tenía solo 2 temas.

Reto: gráfico de temas por año, solo con años completos (1949 a 2019):

Python
plt.plot(themes_by_year.index[:-2], themes_by_year.nr_themes[:-2])

LEGO agregó temas de forma constante hasta mediados de los 90; luego se estancó unos 10 años, hasta comienzos de los 2010.

📖 Explicación conceptual (verificada)

Resultados: 1949 → 2 temas, 1950 → 1; 2019 → 78; el máximo en años completos es 98.

Formas equivalentes de escribir la agregación (todas funcionan en pandas 3):

Python
sets.groupby('year').agg({'theme_id': pd.Series.nunique})       # la del curso
sets.groupby('year').agg({'theme_id': 'nunique'})               # con el nombre como texto
sets.groupby('year').agg(nr_themes=('theme_id', 'nunique'))     # "agregación con nombre": ya queda renombrada
sets.groupby('year')['theme_id'].nunique()                      # una sola operación, sin agg

La "agregación con nombre" es la más clara cuando calculas varias cosas a la vez:

Python
resumen = sets.groupby('year').agg(
    nr_sets=('set_num', 'count'),
    nr_themes=('theme_id', 'nunique'),
    promedio_piezas=('num_parts', 'mean'),
)

5. Dos ejes en un gráfico

(Fuente: 545-superimposing-line-charts-with-separate-axes.md)

📝 Contenido original del curso

Si se grafican sets y temas en el mismo eje, la línea de temas (0 a 90) queda aplastada frente a la de sets (0 a 900). Solución: dos ejes y que comparten el eje x:

Python
ax1 = plt.gca()      # get current axes: el eje actual
ax2 = ax1.twinx()    # un segundo eje y, con el mismo eje x

Luego se grafica en cada eje, con colores distintos, ejes coloreados y etiquetas.

📖 Explicación conceptual (reconstruida y verificada)

Python
ax1 = plt.gca()
ax2 = ax1.twinx()

ax1.plot(sets_by_year.index[:-2], sets_by_year.set_num[:-2], color='g')
ax2.plot(themes_by_year.index[:-2], themes_by_year.nr_themes[:-2], color='b')

ax1.set_xlabel('Año')
ax1.set_ylabel('Número de sets', color='g')
ax2.set_ylabel('Número de temas', color='b')

💡 Cuidado con los dos ejes: como cada eje tiene su propia escala, puedes hacer que dos líneas "se crucen" o "vayan juntas" solo cambiando los límites. Es una herramienta útil, pero también una forma común de engañar con gráficos. Indica siempre qué eje corresponde a cada línea (con el color y la etiqueta) y considera, como alternativa, dos gráficos uno encima del otro.


6. Gráficos de dispersión: piezas por set

(Fuente: 546-scatter-plots-average-number-of-parts-per-lego-set.md)

📝 Contenido original del curso

¿Los sets se volvieron más grandes y complejos? Reto: una serie parts_per_set con el promedio de piezas por año:

Python
parts_per_set = sets.groupby('year').agg({'num_parts': pd.Series.mean})

Reto: un gráfico de dispersión (scatter), que usa puntos, excluyendo las dos últimas observaciones:

Python
plt.scatter(parts_per_set.index[:-2], parts_per_set.num_parts[:-2])

Se ve una tendencia creciente: en los 2010 un set promedio tenía unas 200 piezas, "aproximadamente el doble" que en los 60.

📖 Resultados verificados

Promedio de los promedios anuales: años 60 → 88,5 piezas; años 2010 → 193,7 piezas. Efectivamente, un poco más del doble. Ojo con el último punto: 2021 tiene un promedio de 0 piezas (sus 3 sets son anuncios sin piezas registradas): otra razón para excluirlo.

¿Línea o puntos? Un gráfico de dispersión es mejor cuando cada punto es una observación independiente (el promedio de cada año) y quieres ver una tendencia o la dispersión; uno de líneas, cuando importa la continuidad en el tiempo.

💡 El promedio se deja arrastrar por los sets gigantes. Compara con la mediana ('median'): ¿la tendencia es igual? (Reto 2 de la sección 10.)


7. Esquemas relacionales: claves primarias y foráneas

(Fuente: 547-relational-database-schemas-primary-and-foreign-keys.md)

📝 Contenido original del curso

¿Qué tema tiene más sets? sets['theme_id'].value_counts() dice que el tema 158 tiene 753 sets… pero ¿cómo se llama el tema 158? Los nombres están en themes.csv.

Mini reto: mostrar en el cuaderno el esquema de la base de datos (una imagen de imgur) con <img src="https://i.imgur.com/Sg4lcjx.png">.

Un esquema es cómo está organizada la base de datos. En una base relacional, los datos se reparten en tablas (colores, sets, temas) vinculadas por claves:

  • En themes.csv, cada id es único: es la clave primaria.
  • En sets.csv, theme_id apunta al id de themes.csv: es una clave foránea. Muchos sets pueden tener el mismo tema.

Reto: ¿cómo está estructurado themes.csv? ¿Cuántos id corresponden al nombre "Star Wars"? Busca los sets de esos temas en sets.csv.

Solución: hay 4 temas llamados "Star Wars". El 18 corresponde a productos de 2000 a 2002 con personajes; el 209 agrupa los calendarios de Adviento de Star Wars.

📖 Resultados verificados

Python
themes = pd.read_csv('data/themes.csv')          # 596 filas: id, name, parent_id
themes[themes.name == 'Star Wars']
#       id       name  parent_id
# 17    18  Star Wars        1.0
# 150  158  Star Wars        NaN
# 174  209  Star Wars      207.0
# 211  261  Star Wars      258.0
sets[sets.theme_id == 209]                        # Star Wars Advent Calendar 2013, 2014, 2015...

La columna parent_id, que el curso no comenta, explica por qué hay 4 "Star Wars": los temas forman un árbol. El 158 no tiene padre (es el tema principal); los otros son subtemas que dependen de otros temas (por ejemplo, el 209 es hijo del 207, que agrupa los calendarios de Adviento). Es una clave foránea que apunta a la misma tabla.

Es exactamente lo que construiste en el Día 69 con User, BlogPost y Comment: theme_id es a sets lo que author_id era a blog_posts.


8. Combinar DataFrames y gráficos de barras

(Fuentes: 548-how-to-merge-dataframes-and-create-bar-charts.md y 549-learning-points-y-summary.md)

📝 Contenido original del curso

Para juntar los nombres de los temas con el número de sets por tema se usa .merge(), que combina dos DataFrames por una columna con el mismo nombre. Primero se convierte la serie set_theme_count en un DataFrame con una columna id:

Python
set_theme_count = sets['theme_id'].value_counts()
set_theme_count = pd.DataFrame({'id': set_theme_count.index,
                                'set_count': set_theme_count.values})
merged_df = pd.merge(set_theme_count, themes, on='id')

Star Wars es, en efecto, el tema con más sets. Gráfico de barras de los 10 primeros, con tamaño, etiquetas y los nombres rotados para que no se superpongan:

Python
plt.figure(figsize=(14, 8))
plt.xticks(fontsize=14, rotation=45)
plt.yticks(fontsize=14)
plt.ylabel('Nr of Sets', fontsize=14)
plt.xlabel('Theme Name', fontsize=14)
plt.bar(merged_df.name[:10], merged_df.set_count[:10])

Además de Star Wars, Town o Ninjago, aparecen muchos… ¡libros y llaveros! La categoría "Gear" incluye desde bolsos hasta cartucheras. ¿LEGO se alejó de su negocio principal o se diversificó con éxito? "Eso no lo podemos responder con nuestros datos".

Resumen del día: Markdown y <img>; groupby() con count(); value_counts(); rebanadas df[:-2], df[:10]; .agg(); rename(); dos ejes; dispersión; claves primarias y foráneas; .merge(); barras.

📖 Resultados verificados

# Tema Sets
1 Star Wars 753
2 Gear 656
3 Friends 398
4 Ninjago 356
5 Key Chain 329
6 Basic Set 328
7 Books 310
8 Town 299
9 Supplemental 273
10 Duplo and Explore 248

Los tipos de merge (parámetro how), como en SQL:

how Se queda con
'inner' (por defecto) Solo las claves que están en ambos
'left' Todas las filas del primero; NaN donde no hay coincidencia
'right' Todas las del segundo
'outer' Todas las de ambos

Si las columnas se llaman distinto, no hace falta renombrar: pd.merge(sets, themes, left_on='theme_id', right_on='id').

Ojo: este ranking cuenta cada theme_id por separado. Los 4 "Star Wars" suman más de 753; ¿y si sumaras los subtemas en su tema padre? (Reto 4 de la sección 10.)

💡 Con nombres largos, un gráfico de barras horizontales (plt.barh) se lee mejor que rotar las etiquetas 45°.


9. 📖 Los datos cambian: LEGO en 2026

(Sección creada para esta adaptación.)

Los CSV del curso son de finales de 2020. La fuente original, Rebrickable, publica los datos actualizados para descargar (cdn.rebrickable.com/media/downloads/sets.csv.gz; pandas lee directamente archivos .gz). Verificado el 27/09/2026:

Datos del curso (2020) Rebrickable (septiembre de 2026)
Sets 15 710 28 401
Columnas 5 6 (nueva: img_url)
Años 1949–2021 1949–2027
Set con más piezas The Ultimate Battle for Chima (9987) World Map (2021, 11 695)
Sets en el último año completo 2019: 840 2025: 1432

Dos lecciones:

  1. Las conclusiones tienen fecha. "El set más grande tiene unas 10 000 piezas" era cierto en 2020; hoy no. Incluso las cifras antiguas se corrigen (en los datos actuales, The Ultimate Battle for Chima aparece con 10 001 piezas).
  2. El código bien escrito sobrevive a los datos nuevos. Si filtras años con .loc[:2025] en lugar de [:-2], y seleccionas columnas por nombre, tu cuaderno funciona con el archivo nuevo. Si dependes de posiciones, se rompe en silencio.

10. 🚀 Proyecto del día: el informe de la historia de LEGO

(Integra las lecciones 540 a 549.)

Problema

Queremos contar, con datos, cómo creció LEGO: cuándo despegó, qué temas dominan y si sus sets se volvieron más complejos.

Objetivo

Un cuaderno con Markdown bien presentado que responda las 5 preguntas del curso con tablas y gráficos.

Requisitos funcionales

  1. Encabezados e imágenes en Markdown; el esquema de la base de datos embebido.
  2. Colores únicos y transparentes (dos métodos).
  3. Primeros sets, sets de 1949, los 5 más grandes.
  4. Sets y temas por año (solo años completos), en un gráfico con dos ejes bien rotulado.
  5. Promedio de piezas por año en un gráfico de dispersión.
  6. Los 10 temas con más sets tras un merge, en un gráfico de barras legible.
  7. Conclusiones con al menos una limitación ("no podemos saber si diversificarse fue buena idea").

Restricciones técnicas

  • Años incompletos excluidos por valor, no por posición.
  • Agregaciones con nombre (agg(nombre=('columna', 'función'))).
  • Todos los gráficos con título, ejes y unidades.

Planificación

  1. Comprender el esquema. 2. Entradas: 3 CSV. 3. Procesos: explorar → agrupar → agregar → combinar → graficar. 4. Salidas: el cuaderno. 5. Una sección por pregunta. 6. Dibujar el esquema en papel. 7. Implementar. 8. Comparar con los resultados verificados. 9. Corregir. 10. Concluir.

Construcción paso a paso

  • Versión 1: Markdown y colores.
  • Versión 2: sets más antiguos y más grandes.
  • Versión 3: sets y temas por año, con dos ejes.
  • Versión 4: dispersión de piezas.
  • Versión final: merge, barras y conclusiones.

Pruebas

Comprobación Valor esperado (datos del curso, verificado)
colors['name'].nunique() 135
Transparentes / opacos 28 / 107
Sets en 1949 5
Sets en 2019 840
Tema con más sets Star Wars (id 158, 753)
Temas llamados "Star Wars" 4

🧪 Prueba y depuración

Python
sets_by_year = sets.groupby('year').count()
plt.plot(sets_by_year.index, sets_by_year.set_num)
themes_by_year = sets.groupby('year').agg({'theme_id': nunique})
merged_df = pd.merge(sets['theme_id'].value_counts(), themes, on='id')
plt.bar(merged_df.name, merged_df.set_count)

Encuentra cuatro problemas: el gráfico incluye 2020 y 2021 incompletos; nunique sin comillas ni pd.Series. da NameError; el merge recibe una serie sin columna id (hay que convertirla primero); y el gráfico de barras con todos los temas (cientos) es ilegible: faltan [:10] y la rotación.

⭐ Extensión del proyecto

  • Reto 1: repite el análisis con los datos actuales de Rebrickable y compara (sección 9).
  • Reto 2: grafica la mediana de piezas por año junto al promedio. ¿Cambia la conclusión?
  • Reto 3: agrega a la tabla de temas el nombre del tema padre con un segundo merge de themes consigo misma.
  • Reto 4 — Pensamiento computacional: suma los sets de cada subtema en su tema raíz (el que no tiene parent_id) y rehace el ranking. ¿Sigue ganando Star Wars?

11. 🌟 Proyecto extra: la biblioteca del colegio en tablas relacionadas

(Proyecto creado para esta adaptación; no existe en el curso original.)

Situación

La biblioteca del colegio lleva sus registros en tres hojas de cálculo separadas: libros, préstamos y estudiantes (con código, no con nombre). Nadie ha podido responder "¿qué géneros se prestan más en cada grado?".

Requisitos

  1. Tres CSV ficticios coherentes: libros.csv (id_libro, titulo, autor, genero, anio), estudiantes.csv (codigo, grado) y prestamos.csv (id_prestamo, id_libro, codigo, fecha). Mínimo 40 libros, 60 estudiantes y 200 préstamos (puedes generarlos con random).
  2. Dibuja el esquema (claves primarias y foráneas) en una celda de Markdown.
  3. Con merge, une préstamos con libros y con estudiantes.
  4. Responde: los 10 libros más prestados (barras horizontales); préstamos por género y grado (groupby con dos columnas o pivot_table); préstamos por mes (líneas).
  5. Detecta problemas de integridad: préstamos con un id_libro que no existe (pista: merge con how='left' e indicator=True).

Decisiones que debes tomar (y justificar)

  • ¿Por qué usar un código y no el nombre del estudiante?
  • ¿Qué tipo de merge usas en cada paso y por qué?

Casos de prueba

  • El número de filas del merge préstamos-libros (inner) es igual al de préstamos válidos.
  • Un préstamo "huérfano" aparece como left_only con indicator=True.

12. 🏗️ Proyecto integrador del bloque de datos — Etapa 3

(Proyecto creado para esta adaptación. Descripción completa en el tutorial del Día 75.)

El Observatorio de Datos del Colegio — Etapa 3 (hoy):

  1. Busca en datos.gov.co un segundo conjunto de datos que se pueda combinar con el de la etapa 1 por una columna común (por ejemplo, el código del municipio o el año).
  2. Límpialos, combínalos con merge y verifica cuántas filas se pierden o se duplican con cada tipo de how.
  3. Usa .agg() con nombres para resumir por categoría, y haz un gráfico de barras y uno de dispersión que respondan a otra de tus preguntas.

13. 🧩 Comprueba lo aprendido

Conceptuales

  1. ¿Qué diferencia hay entre groupby().count() y value_counts()?
  2. ¿Por qué hay que excluir 2020 y 2021 de los gráficos del curso?
  3. ¿Qué es una clave primaria? ¿Y una foránea? Da un ejemplo de los datos de LEGO.
  4. ¿Cuándo conviene un gráfico con dos ejes y? ¿Qué riesgo tiene?
  5. ¿Qué hace pd.merge(a, b, on='id') con las filas cuyo id no está en ambos?

Análisis de código

Python
sets.groupby('year').agg(nr_sets=('set_num', 'count'), max_piezas=('num_parts', 'max')).loc[2015:2019]

¿Qué tabla produce? ¿Cuántas filas y columnas?

Predicción

sets[(sets.year == 1949) & (sets.num_parts > 100)] — ¿cuántas filas devuelve con los datos del curso? (Pista: mira la tabla de los primeros sets.)

Depuración

Python
sets[sets.year >= 2000 & sets.num_parts > 1000]

¿Por qué falla? Corrígelo.

Modificación

Cambia el gráfico de barras para que muestre los 10 temas con menos sets (pero al menos 10).

Creación

Escribe el código que encuentre, para cada década (1950, 1960…), el set con más piezas.


14. 🤖 Programar con apoyo de IA

Ciclo de trabajo: formula el problema → inténtalo tú → consulta a la IA → lee y entiende → prueba → compara con la documentación oficial → modifica → explica con tus palabras.

Actividad 1 — ¿Qué merge? Describe a una IA tus tablas de LEGO y pídele el código para unir sets con temas. ¿Usa left_on/right_on o renombra? ¿Qué how eligió? Comprueba cuántas filas resultan con cada opción.

Actividad 2 — Dos ejes honestos. Pide a una IA un gráfico con dos ejes y. Luego pídele que explique cómo ese gráfico podría engañar. Compara con la advertencia de la sección 5.

Actividad 3 — Datos que cambian. Pregunta a una IA cuál es el set de LEGO con más piezas. Verifícalo con los datos actuales de Rebrickable. ¿Coincide? ¿De qué fecha es la información de la IA?


15. 🛠️ Correcciones técnicas al material original

Archivo Afirmación o comportamiento del curso Observación Tratamiento
543, 544, 546 Excluir los años incompletos con [:-2] Depende de la posición; falla con datos nuevos. Mejor .loc[:2019] Nota técnica de la sección 3
542 El set más grande tiene unas 10 000 piezas Cierto con los datos de 2020 (9987); en 2026 el mayor es World Map, con 11 695 (verificado) Sección 9
547 4 temas "Star Wars" Correcto (verificado); la columna parent_id explica que son subtemas Sección 7
544, 546 .agg({'col': pd.Series.nunique}) Funciona; hoy es más común la agregación con nombre Sección 4
545 Dos ejes y Correcto; puede usarse para engañar si no se rotula bien Sección 5
541 is_trans como categoría Es texto 't'/'f', no booleano Sección 1
Todo el día Resultados numéricos Coinciden con los del curso (verificado) Secciones 1 a 8

16. 📋 Matriz de trazabilidad

Contenido original Archivo de origen Concepto desarrollado Ejercicio original Reto adicional Proyecto relacionado
Preguntas sobre LEGO, qué se aprende, cuaderno de inicio, carpeta data 539 Sección 0 Preparar el cuaderno — Sección 10
Celdas de Markdown, <img>, títulos, reto de colores con nunique y transparentes 540 Sección 1 Reto de colores Retos 1–3 de la sección 1 Sección 10
Solución de colores: nunique, groupby().count(), value_counts(), reto de Markdown 541 Sección 1 Solución Booleanos a partir de 't'/'f' Sección 10
Solución de Markdown, sets.csv, primeros sets, 1949, filtrado, sets más grandes, Millennium Falcon 542 Sección 2 Retos de sets Máscaras y condiciones combinadas Secciones 10 y 11
sets_by_year, gráfico, rebanadas [:-2], 840 sets en 2019, datos de 2021 543 Sección 3 Reto de sets por año Filtrar por valor Secciones 10 y 12
.agg() con diccionario, nunique, rename, reto de temas por año 544 Sección 4 Reto de temas por año Agregación con nombre Secciones 10, 11 y 12
Escalas distintas, gca(), twinx(), colores y etiquetas 545 Sección 5 Dos ejes Advertencia sobre gráficos engañosos Sección 10
parts_per_set, agg con mean, reto de dispersión, tendencia 546 Sección 6 Reto de dispersión Media contra mediana Secciones 10 y 12
Sets por tema, value_counts(), esquema, <img>, base relacional, claves primaria y foránea, reto de Star Wars 547 Sección 7 Reto de Star Wars parent_id como árbol Secciones 10 y 11
merge() por id, serie a DataFrame, gráfico de barras, rotación, libros y llaveros 548 Sección 8 Merge y barras Tipos de how, barh, subtemas Secciones 10, 11 y 12
Resumen del día, cuaderno completo 549 Sección 8 — — Sección 10
(No existe en el curso original) — Sección 9 — Datos actuales de Rebrickable Sección 10
(No existe en el curso original) — — — Biblioteca del colegio Sección 11
(No existe en el curso original) — — — Observatorio de Datos, etapa 3 Sección 12

17. 📦 Evidencias de aprendizaje del Día 74

  • El cuaderno del informe de LEGO, con Markdown, imágenes y todos los gráficos.
  • La comparación entre los datos de 2020 y los actuales (Reto 1 del proyecto).
  • El ranking por tema raíz (Reto 4 del proyecto).
  • El análisis de la biblioteca del colegio con su esquema (proyecto extra).
  • La etapa 3 del Observatorio de Datos del Colegio.
  • Cuaderno de errores: años incompletos en el gráfico, rebanadas por posición con datos nuevos, nunique sin comillas, merge con una serie, condiciones sin paréntesis, dos ejes sin rótulos, barras ilegibles, is_trans como texto.