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
- Antes de empezar: preguntas sobre LEGO
- Markdown y HTML en el cuaderno; los colores de LEGO
- Los sets más antiguos y más grandes
- Sets por año y rebanadas
- La función
.agg(): temas por año - Dos ejes en un gráfico
- Gráficos de dispersión: piezas por set
- Esquemas relacionales: claves primarias y foráneas
- Combinar DataFrames y gráficos de barras
- 📖 Los datos cambian: LEGO en 2026
- 🚀 Proyecto del día: el informe de la historia de LEGO
- 🌟 Proyecto extra: la biblioteca del colegio en tablas relacionadas
- 🏗️ Proyecto integrador del bloque de datos — Etapa 3
- 🧩 Comprueba lo aprendido
- 🤖 Programar con apoyo de IA
- 🛠️ Correcciones técnicas al material original
- 📋 Matriz de trazabilidad
- 📦 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_valuesy 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:
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_transusa't'y'f'(texto), noTrue/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_partsconascending=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
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.
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 2021LEGO 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:
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):
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):
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 aggLa "agregación con nombre" es la más clara cuando calculas varias cosas a la vez:
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:
ax1 = plt.gca() # get current axes: el eje actual
ax2 = ax1.twinx() # un segundo eje y, con el mismo eje xLuego se grafica en cada eje, con colores distintos, ejes coloreados y etiquetas.
📖 Explicación conceptual (reconstruida y verificada)
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:
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:
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, cadaides único: es la clave primaria. - En
sets.csv,theme_idapunta aliddethemes.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
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:
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:
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:
- 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).
- 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
- Encabezados e imágenes en Markdown; el esquema de la base de datos embebido.
- Colores únicos y transparentes (dos métodos).
- Primeros sets, sets de 1949, los 5 más grandes.
- Sets y temas por año (solo años completos), en un gráfico con dos ejes bien rotulado.
- Promedio de piezas por año en un gráfico de dispersión.
- Los 10 temas con más sets tras un
merge, en un gráfico de barras legible. - 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
- 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
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
mergedethemesconsigo 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
- Tres CSV ficticios coherentes:
libros.csv(id_libro,titulo,autor,genero,anio),estudiantes.csv(codigo,grado) yprestamos.csv(id_prestamo,id_libro,codigo,fecha). Mínimo 40 libros, 60 estudiantes y 200 préstamos (puedes generarlos conrandom). - Dibuja el esquema (claves primarias y foráneas) en una celda de Markdown.
- Con
merge, une préstamos con libros y con estudiantes. - Responde: los 10 libros más prestados (barras horizontales); préstamos por género y grado (
groupbycon dos columnas opivot_table); préstamos por mes (líneas). - Detecta problemas de integridad: préstamos con un
id_libroque no existe (pista:mergeconhow='left'eindicator=True).
Decisiones que debes tomar (y justificar)
- ¿Por qué usar un código y no el nombre del estudiante?
- ¿Qué tipo de
mergeusas 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_onlyconindicator=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):
- 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).
- Límpialos, combínalos con
mergey verifica cuántas filas se pierden o se duplican con cada tipo dehow. - 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
- ¿Qué diferencia hay entre
groupby().count()yvalue_counts()? - ¿Por qué hay que excluir 2020 y 2021 de los gráficos del curso?
- ¿Qué es una clave primaria? ¿Y una foránea? Da un ejemplo de los datos de LEGO.
- ¿Cuándo conviene un gráfico con dos ejes y? ¿Qué riesgo tiene?
- ¿Qué hace
pd.merge(a, b, on='id')con las filas cuyoidno está en ambos?
Análisis de código
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
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,
nuniquesin comillas,mergecon una serie, condiciones sin paréntesis, dos ejes sin rótulos, barras ilegibles,is_transcomo texto.