lección 2
Día 1 (tarde) — Primer contacto con los datos
Siete ficheros de cinco fuentes distintas en una carpeta compartida. Cárgalos con Pandas, mira qué hay antes de calcular nada (forma, tipos, nulos, grafías) y entiende el modelo: el alumno en el centro, con su canal y su campaña colgando, sus suscripciones que dicen si sigue, sus pagos que dicen cuánto deja y sus matrículas que dicen si aprende. Hoy no limpias: hoy te enteras de a qué te enfrentas.
⏱ 55 min
### La carpeta compartida y sus siete ficheros
Terminada la reunión de la mañana, abres la carpeta compartida que te ha dejado Diego y te encuentras lo de siempre: siete ficheros CSV con nombres que prometen orden y un contenido que ya sospechas que no lo tendrá. De tus cinco encargos anteriores sales con una costumbre que aquí vale oro: no calcular nada el primer día. Antes de sumar un euro o contar un alta hay que saber qué hay dentro de cada fichero, cómo se relacionan y por dónde vienen sucios. Un análisis que arranca sin ese vistazo es un análisis que a media semana descubre que llevaba dos días sumando importes que eran texto, o contando altas por un canal escrito de cuatro maneras distintas. Hoy la tarde es solo para mirar.
1Diego Losada 10:342Buenas! Te dejo en la carpeta compartida las exportaciones de los ultimos ~15 meses:3canales, campanas, usuarios, cursos, suscripciones, pagos y matriculas4Te adelanto el titular: el CUPON es el numero UNO 🙌5Mas altas que ningun otro canal, de calle, y el coste por alta mas bajo. Lo tengo clarisimo6Si me confirmas el CAC por canal ya me vale para llevar el presupuesto al comite del viernes7Corre un poco que quiero cerrar el reparto este trimestre 🙏
El mensaje de Diego: ya trae la conclusión escrita y solo te pide que le confirmes un número. Es justo el patrón del que Nuria te avisó
Fíjate en lo que Diego pide y en lo que no pide. Pide el CAC por canal —el coste por alta—, que es exactamente la métrica que le da la razón. No pide la renovación, ni la finalización, ni el LTV. No porque sea deshonesto, sino porque en su cabeza el trabajo ya está hecho: el cupón es el ganador, solo falta ponerle el número al lado. Tu tarea de esta semana empieza por no aceptar ese marco, pero hoy ni siquiera eso: hoy solo abres los ficheros y miras.
### Pandas, tu banco de trabajo para mirar datos
La herramienta con la que vas a explorar y limpiar estos días es Pandas, una librería de Python pensada para trabajar con datos en forma de tabla. La pieza central se llama DataFrame, y no es más que eso: una tabla con filas y columnas, como una hoja de cálculo, pero manejada con código en lugar de con el ratón. Cargas un CSV con pd.read_csv() y obtienes un DataFrame; a partir de ahí puedes preguntarle cosas a la tabla con métodos, que son órdenes que se escriben con un punto detrás del nombre. Si has usado una hoja de cálculo, ya tienes la intuición: una columna es una columna, una fila es un registro, y lo que en la hoja harías con menús, aquí lo pides con una línea.
¿Y por qué código en lugar de la hoja de cálculo, si al final es lo mismo? Por tres razones que vas a agradecer esta semana. La primera, el tamaño: 250.000 matrículas hacen sudar a cualquier hoja de cálculo, y Pandas las mueve sin pestañear. La segunda, la repetición: la limpieza que hoy escribes se puede volver a ejecutar la semana que viene sobre datos nuevos con un clic, mientras que en la hoja tendrías que rehacerlo a mano cada vez. Y la tercera, la trazabilidad: el código deja escrito exactamente qué hiciste, así que cualquiera —incluido tu yo de dentro de tres meses— puede ver y comprobar cada decisión de limpieza. La hoja de cálculo es estupenda para mirar mil filas y decidir rápido; para 250.000 filas que hay que limpiar igual cada semana y defender ante un comité, el código gana.
Consejo de senior: esto no significa que la hoja de cálculo sea de segunda. Para una pregunta puntual sobre unos cientos de filas, abrir el CSV en una hoja y mirar es a menudo la respuesta más rápida y más sensata, y no hay que avergonzarse de ello. La hoja se queda corta cuando el fichero pesa demasiado, cuando hay que repetir el trabajo cada semana, o cuando dos personas acaban con dos versiones distintas del mismo número. Ahí es donde entra el código. Un buen analista usa las dos y sabe cuándo cada una; no desprecia la hoja ni se aferra a ella.
### El modelo: el alumno en el centro, todo cuelga de él
Siete ficheros no son siete cosas sueltas: son un mapa del negocio, y conviene leerlo antes de tocarlo. En el centro está el alumno, que en los datos es la tabla de usuarios. De cada alumno cuelga todo lo demás. Cuelga su canal (por dónde entró) y, si vino de una campaña de pago, su campana_id. Cuelgan sus suscripciones, que dicen si sigue suscrito o se dio de baja. Cuelgan sus pagos, que dicen cuánto ha dejado en total —el LTV—. Y cuelgan sus matrículas, que dicen a qué cursos se apuntó y cuánto los terminó —si aprende—. Los cursos y los canales son las dos dimensiones de contexto: describen a qué se apuntó y por dónde llegó.
Esta forma —un centro y todo colgando— no es capricho de quien montó la base: es la forma natural de un negocio de suscripción. Como el valor no está en el alta sino en lo que el alumno deja con el tiempo, los datos separan el «quién es y por dónde entró» (usuarios, canales, campañas) de lo que va pasando después (suscripciones, pagos, matrículas). Cada pago es una fila; cada matrícula, otra; cada suscripción, otra. Un mismo alumno tiene una fila en usuarios y muchas en pagos y en matrículas. Eso, que parece un detalle, es la razón de que más adelante haya que tener cuidado al cruzar: si juntas mal, multiplicas filas y los números se disparan.
### El ciclo de vida del alumno en cuatro actos
Para no perderte entre siete tablas, ayuda verlas como los cuatro actos de la vida de un alumno, que es como respira el negocio. Acto primero, la captación: el alumno llega por un canal, quizá empujado por una campaña que costó dinero. Aquí viven usuarios, canales y campañas, y aquí mira Growth. Acto segundo, el aprendizaje: el alumno se matricula en cursos y los termina o no. Aquí viven matrículas y cursos, y aquí mira Producto Educativo. Acto tercero, la permanencia: el alumno sigue suscrito o se da de baja. Aquí viven las suscripciones. Y acto cuarto, el valor: el alumno paga, mes tras mes o año tras año. Aquí viven los pagos, y aquí debería mirar todo el mundo, porque es donde está el dinero.
El drama de AulaViva, y de tu encargo, es que cada área vive obsesionada con un solo acto y ninguna ve la obra entera. Growth aplaude el primer acto (¡cuánta gente entra por el cupón!) sin quedarse a ver el cuarto (¿cuánto pagan?). Y la trampa está justo en el salto entre actos: un canal puede ser brillante en la captación y catastrófico en el valor, y si solo miras el primer acto, nunca lo sabrás. Tu trabajo esta semana es ser el único que se sienta a ver la obra completa, del primer acto al cuarto, y contar cómo termina cada canal. Porque un alumno no es una foto en el momento del alta: es una película de varios meses, y el final —cuánto dejó— es lo que cuenta.
### Hechos y dimensiones: por qué unas tablas son gigantes y otras enanas
Hay un patrón en los tamaños que viste con .shape y que conviene nombrar, porque es la gramática de casi todos los modelos de datos de negocio. Unas tablas son gigantes (170.000 pagos, 250.000 matrículas) y otras diminutas (5 canales, 45 campañas, 600 cursos). No es casualidad: las gigantes son tablas de hechos —registran cosas que pasan, una fila por cada suceso: un pago, una matrícula, una suscripción— y las diminutas son tablas de dimensiones —describen las cosas que participan en esos hechos: los canales, los cursos, las campañas—. Los hechos se acumulan sin parar (cada día hay más pagos); las dimensiones cambian poco (los canales siguen siendo cinco). Reconocer de un vistazo cuáles son hechos y cuáles dimensiones te dice cómo se van a cruzar: los hechos se cuentan y se suman, las dimensiones se usan para agrupar.
Este vocabulario no es solo teoría: te ahorra errores. Cuando quieras «altas por canal», sabes que cuentas un hecho (usuarios) agrupado por una dimensión (canal). Cuando quieras «valor por canal», sumas un hecho (pagos) tras enlazarlo con la dimensión (canal, que vive en usuarios). Y sabes de antemano dónde está el peligro de multiplicar filas: al cruzar dos tablas de hechos grandes, o al unir mal una dimensión. En el caso del CAC de mañana, el error clásico es cruzar campañas (una dimensión con coste) directamente con usuarios (un hecho) por el canal, y que cada campaña se empareje con miles de usuarios. Saber que campañas es una dimensión pequeña y usuarios un hecho grande te avisa del peligro antes de escribir el JOIN.
Esto te lo van a preguntar en una entrevista de analista: «¿qué diferencia hay entre una tabla de hechos y una de dimensiones?». La respuesta corta: una tabla de hechos registra sucesos (pagos, pedidos, clics), crece sin parar y se cuenta o se suma; una de dimensiones describe entidades (clientes, productos, canales), es pequeña y estable, y sirve para agrupar y filtrar. La respuesta que impresiona: y por eso, al cruzarlas, se agrega el hecho y se une la dimensión, nunca al revés, para no multiplicar filas. Dominar este vocabulario te permite hablar de modelos de datos con ingenieros y entender de un vistazo cómo está montada una base que no conoces.
1Toni Marquez 10:412jaja bienvenido/a a las exportaciones de Stripe + el LMS + las herramientas de captacion 🙃3la fecha viene en 3 formatos (una trae el mes en INGLES, "12 Mar 2024", cuidado al parsear),4el importe con € y coma, el avance como "87 %" en texto, y el canal / el plan / la categoria5cada uno escrito como le suena6tres avisos que nadie escucha nunca:71) el webhook de Stripe a veces manda el MISMO pago dos veces en segundos. dedup por pago_id antes de sumar82) el campana_id vacio NO es un nulo que falte: es un alta ORGANICA o de REFERIDO (sin campana de pago). no la tires93) que una suscripcion no tenga fecha_fin NO es que falte el dato: es que sigue ACTIVA. no la confundas con desconocido10hoy solo enterate de que hay, manana lo limpias
El aviso de Toni, tu compañero. Guárdalo entero: los tres puntos son las tres decisiones que deciden si tu análisis sale bien o del revés
El mensaje de Toni es el mejor regalo de la semana, aunque hoy no lo parezca. Te está diciendo, sin que se lo pidas, dónde están las tres minas: los pagos duplicados por el reintento del webhook (el aviso que envía Stripe cuando cobra), el campana_id vacío que no es un error sino un alta orgánica, y la fecha_fin vacía que no es un dato perdido sino una suscripción viva. Hoy no arreglas ninguna; solo compruebas que existen, porque un vistazo honesto es el que te dice el tamaño del trabajo de mañana.
### Explorar es investigar, no ojear
Hay una diferencia enorme entre ojear un fichero y explorarlo, y es la misma que entre mirar la escena de un crimen y investigarla. Ojear es abrir el CSV, ver que tiene columnas con nombres razonables y pensar «vale, esto es lo que dice que es». Explorar es desconfiar: es preguntarle a cada columna si de verdad es lo que su nombre promete, buscar las contradicciones, contar lo que debería cuadrar y sospechar de lo que no. El analista que ojea sale del primer día con una falsa sensación de control y descubre los problemas a media semana, cuando ya ha construido cálculos encima de datos podridos. El que explora sale del primer día sabiendo exactamente dónde están las trampas, y por eso no cae en ellas.
La actitud es la del detective ante una coartada: no se pregunta «¿es plausible?», se pregunta «¿qué tendría que ser verdad para que esto fuera cierto, y lo es?». Cuando ves que hay 40.000 usuarios y 51.601 suscripciones, la mente perezosa piensa «vale, más suscripciones que usuarios, normal, algunos tendrán varias». La mente que investiga piensa «¿de verdad tienen varias, o hay suscripciones duplicadas por reintentos de cobro?». Cuando ves que campana_id sale como decimal, la perezosa lo ignora; la que investiga pregunta «¿por qué un identificador es decimal? ¿tendrá vacíos, y qué significan?». Cada anomalía es una pista, y las pistas no se ignoran: se siguen hasta que confiesan.
Esto te lo van a preguntar en una entrevista: «¿qué es lo primero que haces al recibir un dataset nuevo?». La mala respuesta es «empiezo a analizarlo». La buena es «lo exploro antes de calcular nada: miro forma, tipos, nulos y grafías, y compruebo que las cifras cuadran con lo que sé del negocio». Y la respuesta que te contrata: «además, busco activamente lo que puede estar mal —duplicados, nulos con significado, outliers— porque un análisis construido sobre datos que no he validado es un castillo sobre arena». Demostrar que desconfías de los datos antes de fiarte de ellos es la marca de un analista con oficio.
Y hay una razón profunda para hacerlo el primer día y no sobre la marcha: el coste de un error de datos crece con el tiempo. Una grafía de canal sin normalizar que se detecta el lunes cuesta cinco minutos; la misma detectada el jueves, cuando ya has calculado altas, CAC, finalización y LTV sobre ella, cuesta rehacer toda la semana. Un pago duplicado que se ve hoy es un drop_duplicates; visto el viernes en la demo, cuando Elena pregunta «¿este LTV está deduplicado?» y no lo sabes, es tu credibilidad. Explorar bien el primer día no es perder el tiempo: es la inversión que evita el desastre caro de más adelante.
### Las cinco preguntas de un primer vistazo
Explorar un fichero por primera vez no es mirarlo por encima: es hacerle cinco preguntas concretas, siempre las mismas, que en Pandas se responden con una línea cada una. Primera: ¿qué forma tiene? El atributo .shape devuelve (filas, columnas), y te dice de un vistazo la escala del negocio —decenas de miles de alumnos, cientos de miles de pagos y matrículas, apenas cinco canales—. Segunda: ¿de qué tipo es cada columna? El atributo .dtype de una columna (o .dtypes de todo el DataFrame) te dice si Pandas la leyó como número, fecha o texto; y una columna que sale como object (texto) donde esperabas un número o una fecha es una bandera roja de suciedad.
Tercera: ¿cuántos vacíos hay, y dónde? El método .isnull() marca cada celda vacía como verdadera, y sumándolo con .sum() cuentas los vacíos por columna. Aquí es donde aparecen los dos nulos con significado que avisó Toni. Cuarta: ¿cuántas formas distintas tiene un campo de texto? El método .nunique() cuenta los valores distintos, y .value_counts() los lista con su frecuencia; así ves de golpe que «canal» está escrito de casi veinte maneras. Y quinta, la que se olvida: ¿cuadran las cifras con lo que esperas? Cuarenta mil altas, cinco canales, seiscientos cursos… si un recuento se sale de lo razonable, algo va mal en el fichero, no en el negocio.
Consejo de senior: carga siempre los CSV crudos sin ayudar a Pandas a adivinar tipos, y mira los dtypes antes de nada. Si dejas que Pandas interprete, a veces «acierta» y a veces convierte un importe con coma en un número roto sin avisar. Prefiere verlo sucio y decidir tú: una columna que sale como object es una promesa de trabajo, no un problema oculto. En este caso, fecha_registro, importe, precio, pct_completado y coste van a salir todas como texto, y eso es exactamente lo que esperas.
No te fíes de un recuento hasta haber normalizado las grafías. Si hoy cuentas altas por canal sobre la columna cruda, «cupon», «Cupón» y «CUPON» cuentan como tres canales distintos y el cupón parecerá más pequeño de lo que es. El recuento honesto llega mañana, después de mapear las casi veinte formas a los cinco canales de verdad. Hoy el recuento de grafías te sirve para medir el problema, no para sacar conclusiones de negocio.
### Leer los tipos como una radiografía
De las cinco preguntas, la de los tipos es la que más información esconde por línea, y merece que aprendas a leerla como un médico lee una radiografía: no ves el hueso, ves las sombras que delatan lo que hay debajo. Cuando pides los tipos de una tabla y una columna que debería ser un número (un importe, un precio) sale como object, la sombra dice «aquí hay texto: símbolos, comas, algo que impide que sea número». Cuando una columna que debería ser una fecha sale como object, dice «aquí hay formatos mezclados que Pandas no ha sabido interpretar solo». Y cuando un identificador entero sale como float, dice «aquí hay vacíos». No has abierto una sola celda y ya sabes qué te espera.
1usuario_id int64 <- OK, un entero limpio2canal object <- texto: esperado (hay grafias que normalizar)3campana_id float64 <- SOSPECHOSO: un id deberia ser entero -> hay vacios (nulo con significado)4fecha_registro object <- SOSPECHOSO: una fecha como texto -> formatos mezclados que parsear5ciudad object <- texto: normalizar grafias (MAD/Madrid/madrid)6plan_inicial object <- texto: normalizar (mensual/MES/mes...)
Los tipos de usuarios leídos como radiografía: cada object donde esperabas número o fecha, y el float de un identificador, delatan la suciedad antes de abrir una celda
Este hábito —leer los tipos antes que los datos— es de los que más tiempo ahorran, porque convierte la exploración en algo dirigido en lugar de a ciegas. En vez de ir columna por columna abriendo valores, miras la radiografía, marcas las tres o cuatro columnas sospechosas y vas directo a ellas. Los tipos te dan el mapa de dónde está la suciedad; el resto de la exploración es confirmar cada sospecha. Un analista que empieza abriendo celdas al azar tarda una hora; uno que empieza por los tipos sabe en un minuto qué columnas van a darle trabajo mañana.
### Qué contesta cada fichero (y qué no)
Antes de cerrar conviene fijar, fichero a fichero, qué pregunta contesta cada uno, porque de eso depende no pedirle a una tabla algo que no tiene. Es un error de novato ir a la tabla equivocada: buscar el dinero en las matrículas, o el aprendizaje en los pagos. Cada tabla es dueña de una parte de la historia del alumno, y saber cuál es cuál te ahorra media semana de cruces inútiles.
- canales: la lista de los cinco canales de captación y su tipo (pagado, orgánico, referido, b2b). Es un catálogo pequeño, la dimensión sobre la que gira todo el encargo.
- campanas: las campañas de pago con su coste. Contesta «cuánto costó captar», y solo existe para los canales que pagan (cupón, anuncios, empresas); SEO y referido no tienen campañas.
- usuarios: el alumno y por dónde entró (canal y, si la hubo, campaña). Es el centro: cada fila es una persona, y su canal es la clave de toda la segmentación.
- suscripciones: si el alumno sigue o se fue (la fecha_fin vacía dice «sigue»). Contesta «se queda o se va», que en suscripción es media vida del negocio.
- pagos: cuánto ha dejado cada alumno, en altas y renovaciones. Contesta «cuánto vale» (el LTV) y «vuelve a pagar» (la renovación). Es donde vive el dinero.
- matriculas: a qué cursos se apuntó y cuánto los terminó. Contesta «aprende o no» (la finalización), que es la causa de todo lo demás.
- cursos: la ficha de cada curso (categoría, nivel, duración). Es la dimensión de contexto y la que permite el control de confusión del jueves.
Fíjate en un detalle de la lista que decide el análisis: el dinero (pagos) y el aprendizaje (matrículas) viven en tablas distintas y ninguna sabe por qué canal entró el alumno. El canal solo está en usuarios. Por eso, para responder «cuánto vale el canal cupón», no basta con una tabla: hay que salir de usuarios (que tiene el canal), bajar a suscripciones (que enlaza con los pagos), sumar los pagos (el valor) y, por otro lado, ir a las matrículas (el aprendizaje). Cuatro tablas para un solo número. Esa es la razón de que este encargo no se resuelva en Looker, cuyos paneles miran cada tabla por separado.
### Un nulo que sí es un error: el método de pago
Toni te avisó de dos nulos con significado (el campana_id y la fecha_fin), pero conviene que sepas distinguirlos de un nulo normal y corriente, porque no todos los vacíos son especiales. En la tabla de pagos, la columna del método de pago (tarjeta, PayPal, bizum) tiene también algunos vacíos, y esos sí son lo que parecen: datos que no se registraron, método desconocido. Un nulo real. La diferencia es toda: un nulo con significado hay que interpretarlo (el campana_id vacío ES una categoría, «orgánico»), mientras que un nulo real solo se constata (no sabemos con qué pagó, y punto). Confundirlos en el otro sentido —tratar el campana_id vacío como «desconocido» y tirarlo— es el error que invierte el análisis.
La regla para no equivocarte con un vacío: pregúntate «¿este vacío me dice algo, o solo me falta el dato?». Si el vacío significa una categoría real (sin campaña = orgánico; sin fecha_fin = activa), es un nulo con significado y se conserva e interpreta. Si el vacío es simplemente ausencia de información (no sé con qué método pagó), es un nulo real y se trata como tal (se cuenta como «desconocido», no se inventa). El método de pago vacío no cambia ni el LTV ni la renovación, así que no te preocupa; los otros dos deciden el caso. Saber cuál es cuál es criterio, no sintaxis.
### Lo que sabes al cerrar la tarde
Guarda esta idea para toda la semana: un vistazo honesto al principio ahorra un desastre al final. Y ahora sí, el resumen. Al final del día no has calculado ni una tasa, y está bien: tienes el mapa. Sabes que son cuarenta mil alumnos que entraron por cinco canales, que dejan más de ciento setenta mil pagos y casi doscientos cincuenta mil matrículas, y que cada fuente exporta la suciedad a su manera. Sabes que el canal viene en casi veinte grafías, que las fechas traen una forma con el mes en inglés, que los importes y el avance son texto, y que hay dos vacíos que no son errores. Mañana limpias y, sobre todo, decides qué es el valor de un canal. Pero hay algo que no puedes limpiar con una función: la diferencia entre un vacío que sobra y un vacío que significa. Eso no es limpieza, es criterio, y es lo primero que tocas mañana.
Consejo de senior: dedica el primer contacto con unos datos a entenderlos, no a impresionar con un resultado rápido. Es tentador, sobre todo con un jefe con prisa como Diego, sacar un número el primer día para parecer productivo. Pero un número sacado sobre datos que no has mirado es una promesa que tendrás que retirar. Vale más llegar mañana con «he mapeado el modelo, sé dónde están las tres trampas y mañana tengo las cifras limpias» que hoy con una cifra que el jueves resulta estar calculada sobre canales mal contados. La productividad de un analista no se mide en números por hora, sino en números que aguantan.
Regístrate para guardar tu progreso.