lección 2
Día 1 — Tu primer encargo y los datos
Siete ficheros, ninguna documentación. Cargas los CSV con Pandas, miras qué hay de verdad dentro, y aprendes a leer las relaciones entre tablas antes de calcular una sola cifra.
⏱ 50 min
### Siete ficheros y ni un manual
Abres la carpeta compartida que te dejó Nuria y ahí están: siete ficheros CSV, ni un documento que explique qué es cada columna. Ya tienes claras las preguntas que quieres responder —las encuadraste ayer con Diego—, pero una pregunta no se responde sola: necesita datos, y ahora mismo esos datos son siete cajas cerradas con etiquetas escritas a mano. El primer trabajo de hoy no es calcular nada. Es abrir las cajas y mirar qué hay dentro. En el oficio esto se llama exploración, y saltárselo es la forma más rápida de dar un número equivocado con total seguridad.
Un CSV (fichero de valores separados por comas, del inglés comma-separated values) es la forma más simple de guardar una tabla en un fichero de texto: una fila por línea, las columnas separadas por comas. Es el formato universal para mover datos entre sistemas, y también el que más problemas esconde, porque no guarda el tipo de cada columna. Un precio, una fecha y un nombre son, para un CSV, exactamente lo mismo: texto. Por eso lo primero que se hace al cargarlo es preguntarle a Pandas qué cree que es cada cosa.
Pandas es la librería de Python con la que casi todos los analistas mueven datos. Su pieza central es el DataFrame: una tabla en memoria, con filas y columnas, sobre la que puedes filtrar, agrupar, cruzar y calcular. Piénsalo como una hoja de cálculo a la que hablas con código en lugar de con el ratón: lo mismo que harías arrastrando y soltando, pero repetible, rápido y sin miedo a estropear el original.
¿Y por qué no usar directamente una hoja de cálculo, si es más cómoda? Para muchas cosas la usarías, y no pasa nada. Pero fíjate en tres muros con los que una hoja choca y Pandas no. El primero es el tamaño: una hoja se arrastra o se cuelga con cientos de miles de filas, y aquí tienes una tabla de más de veinte mil líneas que además hay que cruzar con otras seis. El segundo es la repetición: si el mes que viene llega otra campaña con los mismos ficheros sucios, en la hoja repites toda la limpieza a mano; en Pandas vuelves a ejecutar el mismo código y listo. El tercero, el más silencioso, es que en una hoja tocas los datos originales con el ratón y no queda rastro de qué hiciste; en Pandas cada paso está escrito, así que cualquiera puede leer exactamente cómo llegaste a un número. Esa trazabilidad es justo lo que pide Diego cuando dice que un número tiene que poder defenderse.
### Los siete ficheros de BrightCart
Antes de mirar dentro, lee los nombres. Los ficheros de una empresa cuentan una historia solo con cómo se llaman: hay tablas de «quién» (clientes), de «qué» (productos), de «cuándo y cómo» (pedidos, campaña) y de «qué pasó con cada cosa» (líneas de pedido, devoluciones, visitas). Aprender a leer un conjunto de ficheros como un mapa del negocio, antes de abrir ninguno, es una habilidad que ahorra horas. Estos son los siete y lo que guarda cada uno:
- clientes.csv — quién compra: identificador, ciudad, género, edad, fecha de registro.
- productos.csv — el catálogo: nombre, categoría, temporada, colección, coste y precio base de cada producto.
- campana.csv — la ficha de cada campaña: fechas, canal, presupuesto y ventas del año anterior.
- pedidos.csv — cada pedido: qué cliente, qué día, por qué canal, con qué método de pago, y de qué campaña (si viene de una).
- lineas_pedido.csv — el detalle de cada pedido: qué producto, qué talla, cuántas unidades, a qué precio y con qué descuento. Es la tabla más importante.
- devoluciones.csv — lo que vuelve: qué línea de pedido se devolvió, cuándo, en qué talla y por qué motivo.
- visitas_web.csv — el tráfico de la web: sesiones por día y por canal.
Lo que acabas de leer, ese listado de qué significa cada fichero y cada columna, tiene nombre: se llama diccionario de datos. Es el documento que debería existir en toda empresa y que casi nunca existe: una tabla que dice, para cada columna, qué es, en qué unidad está y qué valores puede tener. En BrightCart no lo hay, y por eso Nuria te ha pasado siete cajas sin etiqueta interior. Parte de tu trabajo esta semana es reconstruirlo tú a base de mirar, y si al terminar lo dejas escrito para el siguiente, habrás hecho más por el equipo que muchos análisis.
Consejo de senior: cuando no haya diccionario de datos, créalo mientras exploras, aunque sea en cuatro líneas por fichero. Anota qué es cada columna, en qué unidad viene y qué rareza le has visto («el precio trae el euro pegado», «hay clientes duplicados»). Ese cuaderno de notas es oro: te ahorra volver a descubrir lo mismo dentro de un mes, y convierte tu exploración en un activo del equipo en vez de en trabajo que muere en tu cabeza.
### El checklist de exploración: mirar antes de tocar
Para cada fichero nuevo, siempre las mismas preguntas, siempre en el mismo orden. Cuántas filas y columnas tiene (`.shape`). Qué pinta tienen las primeras filas (`.head()`). Qué cree Pandas que es cada columna (`.info()` y `.dtypes`). Y dónde faltan datos (`.isnull().sum()`). Es tu rutina de detective al llegar a la escena: no tocas nada, primero observas y anotas.
1import pandas as pd23# Los CSV del caso estan montados en la carpeta datos/4clientes = pd.read_csv('datos/clientes.csv')56print(clientes.shape) # (filas, columnas)7print(clientes.head()) # primeras 5 filas8print(clientes.dtypes) # que tipo tiene cada columna9print(clientes.isnull().sum()) # cuantos nulos hay por columna
La rutina de exploración: shape, head, dtypes, nulos. Siempre en ese orden.
La línea que más te va a hablar de las cuatro es `.dtypes`. Pandas, al cargar un CSV, adivina el tipo de cada columna: si ve solo números, la marca como número (`int64` o `float64`); si ve cualquier cosa rara —un euro, una coma, una letra— se rinde y la marca como `object`, que es su forma de decir «esto es texto». Por eso, cuando veas `object` en una columna que debería ser un precio o una fecha, no es un misterio: es la prueba de que ahí dentro hay suciedad que impide que sea número. `.dtypes` es tu primer detector de problemas, y lo lees antes de calcular nada, porque sumar una columna que Pandas cree que es texto o no funciona o, peor, funciona mal.
Nunca abras un CSV de trabajo directamente en Excel para «echarle un ojo rápido». Excel modifica cosas sin avisar: convierte códigos con ceros delante en números y pierde el cero, reinterpreta las fechas según tu idioma, y a veces trunca filas. Para el primer vistazo se usa Pandas, que no toca el original.
### Cómo se cruzan las tablas
Ninguna de tus preguntas se responde con una sola tabla. «¿Qué producto vendió más?» necesita las líneas de pedido (cuántas unidades) y el catálogo (el nombre del producto). «¿Cuánto se devolvió del Alma?» necesita cruzar devoluciones con líneas y con productos. Las tablas se conectan por identificadores compartidos: una columna que en una tabla es la clave y en otra apunta a ella. Es como el número de socio de una biblioteca: aparece en tu carnet y en cada préstamo, y por eso se puede saber qué libros tienes tú.
En el centro está `lineas_pedido`: cada fila es un artículo concreto que alguien compró, con su talla, su cantidad y su precio. Es la tabla de hechos, la que registra lo que de verdad pasó. A su alrededor están las tablas de contexto, que explican cada hecho: `pedidos` dice cuándo y por qué canal, `productos` dice qué es y cuánto cuesta, `clientes` dice quién compró, `campana` dice si venía de una promoción, y `devoluciones` dice si volvió. Entender este mapa ahora te ahorra media semana de confusión después.
Hay una palabra que resume por qué `lineas_pedido` y `pedidos` son tablas distintas, y la vas a oír mucho: granularidad. La granularidad es «a qué nivel de detalle está cada fila». En `pedidos`, una fila es una compra entera: «el pedido 500002, del cliente 4937, el 2 de julio». En `lineas_pedido`, una fila es un artículo dentro de esa compra: «en el pedido 500002, un Vestido Alma talla M». Un pedido de tres prendas es una fila en `pedidos` y tres en `lineas_pedido`. Confundir estos dos niveles es la fuente número uno de cifras mal calculadas: si cuentas filas de `lineas_pedido` creyendo que cuentas pedidos, te sale el triple. Por eso Diego pregunta siempre «¿a qué nivel?» antes de aceptar un número.
Piénsalo con el ticket del supermercado, que es la misma estructura. El ticket entero (con su fecha, su total y su forma de pago) es el «pedido». Cada línea impresa del ticket —«2 × leche», «1 × pan»— es una «línea de pedido». Si te preguntan «¿cuántas compras hiciste este mes?» cuentas tickets; si te preguntan «¿cuántos productos distintos compraste?» cuentas líneas. La misma caja registradora, dos preguntas, dos niveles de detalle. En BrightCart es idéntico, solo que en vez de un ticket de papel tienes dos tablas cosidas por `pedido_id`.
Antes de que te pongas con los ficheros, Diego te deja una nota en el canal del equipo que resume el espíritu del día:
1Diego 11:022Regla para hoy: no calcules nada todavia. Solo mira.3Abre cada fichero, cuenta filas, mira los tipos y apunta las rarezas.4Cuando sepas decirme "esta es la tabla de hechos, estas la5contextualizan, y estas columnas vienen sucias", has terminado el dia.6Explorar bien hoy es lo que hace que manana los numeros salgan a la7primera. Nadie ve este trabajo, y es el que mas errores evita.
La exploración no se luce, pero es lo que sostiene todo lo que viene después.
Consejo de senior: cuando llegues a un proyecto nuevo, dibuja este mapa en un papel antes de escribir código. Qué tabla es la de hechos (normalmente la que más filas tiene y la que registra transacciones) y por qué columnas se engancha a las demás. Diez minutos de dibujo te evitan cruces mal hechos que dan cifras plausibles pero falsas, que son las peores de detectar.
Antes de terminar el día, Álex te escribe. Ya intuye por dónde vas y te suelta, medio en broma, el aviso que nadie del equipo le compra:
1Alex Pena 13:412jajaja bienvenida/o a los CSV de Nuria3la fecha viene en tres formatos, el precio con simbolo de euro y coma,4y las categorias cada una escrita como le da la gana5manana lo limpias, hoy solo enterate de que hay6y oye, ojo con las devoluciones, que en moda son media pelicula
Álex ya sabe lo que te espera mañana. Y suelta, otra vez, lo de las devoluciones.
### El diccionario de datos que vas a dejar escrito
Recuerda lo que echabas de menos al abrir la carpeta: nadie te dijo qué era cada columna. Esa ausencia tiene un remedio barato, y es la clase de gesto que hace que un junior deje huella en un equipo. Mientras exploras, ve anotando lo que descubres de cada columna: qué representa, en qué unidad viene, y qué rareza le has visto. Al terminar, tendrás algo que en BrightCart no existía: un diccionario de datos. No es un documento solemne; pueden ser cuatro líneas por fichero en un bloc de notas. Pero convierte tu media hora de exploración en un activo que el equipo entero reutiliza, en vez de en conocimiento que se muere en tu cabeza cuando cierras el portátil.
Así de sencillo puede ser el diccionario de la tabla de líneas, escrito con lo que ya sabes tras explorar:
- linea_id — identificador único de la línea. Número entero. Es la clave: no se repite (salvo los duplicados de exportación que hay que quitar).
- pedido_id — a qué pedido pertenece la línea. Número entero. Apunta a la tabla pedidos.
- producto_id — qué producto es. Número entero. Apunta a la tabla productos.
- talla — la talla comprada. Texto, y viene sucia: "M", "m", "Talla M" son la misma. Hay que normalizar.
- cantidad — unidades de esa línea. Número entero. Ojo: hay ceros y negativos imposibles que hay que excluir.
- precio_unitario — precio de catálogo por unidad. Viene como texto con "€" y coma decimal ("29,99 €"): hay que convertir a número.
- descuento_pct — descuento aplicado. Viene en tres formatos ("20%", 0.2, 20): hay que normalizar a fracción 0-1.
Consejo de senior: el mejor momento para escribir el diccionario de datos es mientras exploras, no después, porque después no llega nunca. Cada vez que descubras qué es una columna o le veas una rareza, anótalo en el acto. Ese documento te sirve tres veces: hoy, para no repetir exploraciones; el viernes, para defender tus cifras; y dentro de un mes, cuando llegue otra campaña con los mismos ficheros y tú (o quien venga detrás) no tenga que redescubrir que el precio trae el euro pegado.
### Contar filas no es contar cosas
Hay una trampa en la exploración que atrapa a casi todos los junior el primer mes, y quiero que la veas hoy para que no te pille. Cuando cargas un fichero y haces `len(df)`, obtienes el número de filas. Es tentador leer ese número como «cuántas cosas hay». Pero una fila no siempre es una cosa distinta. En `clientes.csv` hay más filas que clientes, porque algunos están repetidos. En `devoluciones.csv` hay filas que apuntan a líneas que no existen. Contar filas te da el tamaño del fichero, no el tamaño de la realidad. Son dos números distintos, y confundirlos es la forma más silenciosa de dar una cifra inflada.
Por eso, junto a `len(df)`, un analista mira siempre dos cosas más al explorar: cuántos valores distintos hay en la columna que identifica cada cosa (`df["cliente_id"].nunique()`), y cuántas filas están repetidas de principio a fin (`df.duplicated().sum()`). Si el número de filas y el de identificadores únicos no coinciden, hay duplicados, y toca decidir qué hacer con ellos antes de contar nada. Es la diferencia entre «este fichero tiene 5.010 filas» y «en este fichero hay 4.970 clientes, algunos metidos dos veces». La segunda frase es información; la primera es solo un tamaño.
Consejo de senior: cada vez que vayas a dar un «cuántos», párate medio segundo y pregúntate si estás contando filas o cosas. «Cuántos clientes» casi nunca es len(df): es nunique() del identificador. «Cuántos pedidos» no es len(lineas): es nunique() de pedido_id. El día que interiorices que una fila no es automáticamente una cosa, dejarás de dar por accidente cifras que se pasan del doble.
No confundas «filas repetidas» con «cosas que se repiten legítimamente». Que un cliente aparezca en veinte líneas de pedido no es un duplicado: es que compró veinte veces, y está bien. Un duplicado de verdad es la MISMA fila entera repetida (un fallo de exportación), o el mismo identificador de cliente metido dos veces en la tabla de clientes. La diferencia importa: si eliminas «repetidos» sin mirar qué tabla estás tocando, puedes borrar ventas reales creyendo que limpias. Antes de quitar duplicados, ten claro qué debería ser único en esa tabla.
Álex, que ya ha visto a más de un junior tropezar con esto, te deja un último mensaje antes de irse:
1Alex Pena 17:522un ultimo consejo y me voy3cuando cuentes clientes o pedidos usa nunique(), no len()4el fichero de clientes trae repes y el de devoluciones trae basura5que no existe. si cuentas filas a pelo te sale de mas y no sabes6por que. manana con los datos limpios esto ya no muerde tanto7pero hoy que lo tengas en la cabeza
El aviso que evita el error de contar más de la cuenta.
### La tabla de hechos y las tablas de contexto
Antes de cerrar el día conviene que le pongas nombre a algo que ya has intuido mirando el diagrama de tablas. De las siete, hay una que es distinta de las demás: lineas_pedido. Es la que guarda lo que de verdad pasó, línea a línea: este producto, en esta talla, esta cantidad, a este precio. Todo lo que vas a calcular esta semana —ingresos, unidades, devoluciones, márgenes— sale de ahí. A una tabla así se la llama, en la jerga, la «tabla de hechos»: registra hechos que ocurrieron, uno por fila. Las demás (productos, clientes, campana) son «tablas de contexto» o «de dimensiones»: no cuentan qué pasó, sino que describen a los actores. Productos te dice qué es cada producto, clientes quién es cada cliente, campana qué campaña es cuál.
La analogía que a mí me ordenó esto para siempre es la de un tique de la compra. El tique en sí —cada línea con su producto, su cantidad y su precio— es la tabla de hechos: es lo que ocurrió en la caja. El folleto del supermercado con la descripción de cada producto, el carné del cliente con sus datos, el cartel de «semana del pescado» que había ese día: eso es contexto. Ninguno de los tres es una venta; los tres te ayudan a entender las ventas. Cuando quieras saber «cuánto se vendió de la marca X», partes del tique (los hechos) y le pegas el folleto (el contexto) para saber qué líneas eran de esa marca. Ese «pegar» es el cruce por identificador que harás sin parar.
Esta distinción no es un capricho académico: te dice por dónde empezar cualquier análisis. La pregunta «¿por dónde arranco?» casi siempre se responde igual: por la tabla de hechos, filtrando las filas que te interesan (las de la campaña, las de una semana), y luego pegándole el contexto que necesites para agrupar (la categoría del producto, el canal del pedido). Si algún día abres una base de datos nueva y no sabes por dónde entrar, busca primero la tabla de hechos: la que tiene muchas filas y un montón de identificadores apuntando a otras tablas. Esa es la que registra el negocio.
Consejo de senior: cuando llegues a una empresa y te den acceso a las tablas, tu primera pregunta debería ser «¿cuál es la tabla de hechos y a qué nivel está cada fila?». En unas es la línea de pedido, en otras el pedido entero, en otras un evento de la web. Saber eso te ahorra la mitad de los errores de conteo, porque ya sabes qué representa una fila antes de sumar nada. Es la misma pregunta de Diego —«¿a qué nivel?»— pero hecha a la estructura de los datos, no a un cálculo concreto.
Cuidado con un espejismo muy de junior: creer que «los datos ya están» porque los ficheros se abren sin error. Que un CSV cargue no significa que esté listo para calcular. Hoy has abierto las siete tablas y todas «funcionan», y sin embargo mañana vas a pasar media jornada limpiándolas. Cargar es abrir la caja; entender qué hay dentro y si se puede usar es otra cosa. El error de dar por buenos unos datos solo porque el ordenador no se ha quejado es de los que cuestan un análisis entero.
Hoy solo tenías que enterarte de qué hay, y ya lo sabes: siete tablas, un centro claro —la tabla de hechos— y unos cuantos identificadores que las cosen. Pero al mirar los tipos con `.dtypes` has visto lo que anunciaba Álex: la fecha es texto, el precio es texto con un euro pegado, y las categorías están escritas de tres maneras. Nada de eso se puede calcular tal cual. Mañana toca ensuciarse las manos de verdad: dejar los datos en un estado en el que sumar, agrupar y comparar signifique algo.
Regístrate para guardar tu progreso.