Power Query¶
Ejercicio power-query-annex.pdf · PDF
Test rápido, sin mirar. En la lección anterior ejecutaste un script y apareció games_clean. ¿Qué le hizo ese script a price? ¿Y a owners?
Si has tenido que pensarlo, bien. Ahora la pregunta de verdad: ¿cómo lo averiguarías? Abres el archivo .sql y lo lees. Cada decisión está escrita ahí, en orden. Ese archivo es la receta de tu limpieza.
Aquí viene el problema. La mayoría de la gente que limpia datos en el trabajo no escribe nunca SQL. Hace clics. Así que hoy limpias el mismo archivo haciendo clics, en Power BI, y te haces una sola pregunta todo el rato: cuando haces clic, ¿adónde va la receta?
Qué aprenderás
- Qué es Power Query y cómo abrir su editor desde Power BI Desktop
- Cómo leer una lista de Applied Steps y decir qué le hizo cada paso a la tabla
- Cómo rehacer con clics la limpieza de esta unidad: reemplazar valores, cambiar tipos, añadir una columna condicional
- Qué SQL de los que ya conoces equivale a cada clic
- La trampa: por qué el texto
9.99no es el mismo número en todos los ordenadores (la configuración regional, o locale) - Cuándo elegir Power Query y cuándo elegir SQL
Una cocina que escribe la receta¶
Power Query es la parte de Power BI que prepara los datos antes de usarlos: se conecta a una fuente y después limpia y reorganiza la tabla paso a paso.
Conociste Power BI en Obtener datos con Power BI. Allí pulsaste Load y cogiste los datos tal como venían. Power Query es la sala que te saltaste: la que queda entre la fuente y el informe.
Piensa en dos cocinas.
En la cocina SQL escribes primero toda la receta y luego la cocina la cocina. Eso fue games_clean.sql.
En la cocina Power Query simplemente cocinas. Pero hay un cuaderno en la pared que apunta cada movimiento que haces, una línea por movimiento. Cuando terminas, la receta está ahí, y no la has escrito tú.
Mismo plato. Y en las dos cocinas el ingrediente en bruto, el archivo CSV, no se toca nunca.
flowchart LR
CSV["<b>video_games.csv</b><br>el ingrediente en bruto:<br>nunca se modifica"]
subgraph PQ ["Power Query (la cocina que escribe la receta)"]
direction LR
S1["Source"] --> S2["Promoted Headers"] --> S3["Changed Type"] --> S4["tus pasos..."]
end
CSV --> S1
S4 --> M["<b>Tabla en Power BI</b><br>el plato: limpio,<br>listo para los gráficos"]
Power BI Desktop solo funciona en Windows
Power BI Desktop es un programa de Windows. Si no tienes un ordenador con Windows, puedes seguir esta página igualmente: cada paso de Power Query de abajo tiene un gemelo en SQL que puedes ejecutar en SQL Lab, y los números tienen que coincidir.
El Power Query Editor¶
Abre Power BI Desktop y ve a Home → Get data → Text/CSV. Elige video_games.csv (descárgalo de la página de Recursos). En la ventana de vista previa pulsa Transform Data, no Load. Se abre una segunda ventana.
El Power Query Editor es la ventana donde ves una vista previa de tu tabla y le aplicas transformaciones.
| Parte | Dónde | Qué es |
|---|---|---|
| Ribbon | Arriba | Las pestañas con todas las transformaciones: Home, Transform, Add Column, View |
| Queries pane | Izquierda | Una consulta por cada tabla que has traído. Hoy hay una: video_games |
| Data preview | Centro | Una vista previa de la tabla después del paso seleccionado. No es el archivo entero |
| Query settings | Derecha | El nombre de la consulta y la lista de Applied Steps |
Applied Steps es la lista de todas las transformaciones hechas a la tabla, en el orden en que se hicieron. Es el cuaderno de la pared de la cocina.
Míralo ahora. Ya tiene tres líneas y todavía no has hecho nada:
| Paso | Qué hizo Power Query por su cuenta |
|---|---|
| Source | Abrió el archivo |
| Promoted Headers | Cogió la primera fila y la usó como nombres de columna |
| Changed Type | Adivinó un tipo para cada columna mirando los valores |
Esa tercera línea merece sospecha. En Tipos y formatos la regla era: cuando conviertes, declaras el formato, nunca dejas que la herramienta adivine. Power Query sí adivina, y adivina a partir de las primeras 200 filas del archivo. Mira el pequeño icono a la izquierda del nombre de cada columna: muestra el tipo que se ha elegido. Dentro de un momento corregirás dos de esas suposiciones.
Mira antes de limpiar¶
En Calidad de los datos auditaste la tabla con consultas COUNT antes de arreglar nada. Power Query tiene ese mismo hábito integrado.
En la pestaña View, marca Column quality y Column distribution. Bajo el nombre de cada columna aparece una barrita con el porcentaje de valores Valid, Error y Empty.
Ahora mira metascore. En SQL descubriste que 23,838 de las 26,688 filas no tienen Metascore: el 89%. ¿Está de acuerdo Power Query?
Antes de fiarte de lo que lees, mira la esquina inferior izquierda de la ventana. Dice Column profiling based on top 1000 rows. Haz clic en ese mensaje y cambia a Column profiling based on entire data set.
Cuidado: la primera lectura era una muestra
Por defecto, Power Query perfila solo las primeras 1,000 filas. Tu archivo tiene 26,688. Un porcentaje calculado con el 4% de la tabla puede quedar muy lejos de la verdad, sobre todo si el archivo está ordenado. Cambia siempre a todo el conjunto de datos antes de apuntar un número.
Hay una segunda sorpresa, y es la idea más importante de esta página. En este CSV, "vacío" no está vacío. Son las dos letras NA:
47,Half-Life 2: Deathmatch,"Nov 1, 2004",4.99,"5,000,000 .. 10,000,000",Valve,Valve,0,0,NA
Cuando subiste el archivo a Superset, la subida convirtió cada NA en un NULL de verdad, y nunca viste las letras. Power Query no asume eso. Para Power Query, NA es un trozo de texto como cualquier otro hasta que le dices lo contrario. Decírselo es tu primer paso.
La misma limpieza, dos veces¶
Seis pasos. Para cada uno tienes los clics en Power Query, el gemelo en SQL sobre la tabla games y un número que demuestra que ambos hicieron lo mismo. Después de cada clic, mira Applied Steps: ha aparecido una línea nueva.
Paso 1 — NA significa vacío. Selecciona la columna price. Transform → Replace Values: Value to find NA, Replace with null.
En SQL no hay nada que escribir: la subida ya lo hizo. Cuenta el resultado.
SELECT COUNT(*) - COUNT(price) AS empty_prices FROM games;
Respuesta: 3,095 precios están vacíos.
Paso 2 — price es un número, escrito a la americana. Clic derecho en la cabecera de price → Change Type → Using Locale... → Data type: Decimal Number, Locale: English (United States).
En SQL, price ya es un número. Pero pregúntate quién decidió que 9.99 usa un punto para los decimales. La siguiente sección trata de esa pregunta.
Paso 3 — is_free, y luego rellenar. Dos movimientos, en este orden.
Primero, Add Column → Conditional Column: nombre de la columna nueva is_free; si price equals null entonces true, si no false.
Después, Replace Values en price: null → 0.
SELECT COUNT(*) AS free_games
FROM (SELECT COALESCE(price, 0) AS price, (price IS NULL) AS is_free FROM games) AS t
WHERE is_free;
Respuesta: 3,095 filas quedan marcadas como gratuitas. El mismo número que en el paso 1, como debe ser.
Paso 4 — owners se convierte en un número. La columna contiene texto como 10,000,000 .. 20,000,000. Selecciónala y luego:
- Transform → Extract → Text Before Delimiter, delimitador
.. - Replace Values:
,→ nada - Replace Values otra vez, con Advanced options → Replace using special characters → Non-breaking Space → nada
- Cambia el tipo a Whole Number
El tercer punto es el espacio invisible contra el que luchaste en Unidades y duplicados: parece un espacio y no lo es.
SELECT MAX(REGEXP_REPLACE(SPLIT_PART(owners, '..', 1), '[^0-9]', '', 'g')::bigint) AS max_owners_min
FROM games;
Respuesta: 100,000,000. Ese es Dota 2.
Paso 5 — release_date se convierte en fecha. Clic derecho en la cabecera → Change Type → Using Locale... → Date, English (United States). Después mira Column quality: ¿hay algún Error?
En SQL esto era el CASE con dos llamadas a TO_DATE. Cuenta cuántas filas encajan en cada formato:
SELECT COUNT(*) FILTER (WHERE release_date ~ '^[A-Z][a-z]{2} [0-9]{1,2}, [0-9]{4}$') AS full_dates,
COUNT(*) FILTER (WHERE release_date ~ '^[A-Z][a-z]{2} [0-9]{4}$') AS month_only
FROM games;
Respuesta: 26,646 fechas completas como Nov 16, 2004, y 41 con solo el mes, como Jun 2009. Eso deja exactamente una fila que no encaja en ninguno: 8 Oct, 2014. Averigua qué hace Power Query con esas 42 filas raras. Haga lo que haga, Column quality te lo dirá.
Paso 6 — una banda y un filtro. Add Column → Conditional Column: nombre price_band, con una rama por banda (Free, Under 5, 5 to 15, 15 to 30, 30 or more). Después haz clic en la flecha del filtro en la cabecera de game y desmarca NA.
En SQL: el CASE WHEN de Categorización y WHERE game IS NOT NULL.
SELECT COUNT(*) FROM games WHERE game IS NOT NULL;
Respuesta: 26,685 filas. Los tres juegos sin nombre han desaparecido.
Para terminar, pulsa Home → Close & Apply. Hasta ahora trabajabas sobre una vista previa. Ahora los pasos se ejecutan sobre el archivo entero y la tabla aterriza en Power BI.
Tu lista de Applied Steps queda así (los pasos repetidos llevan un número):
| Paso aplicado | Qué hizo | Gemelo en SQL |
|---|---|---|
| Source, Promoted Headers, Changed Type | Abrió el archivo, nombró las columnas, adivinó los tipos | La subida del CSV |
| Replaced Value | NA → null en price |
Hecho por la subida |
| Changed Type with Locale | price como número decimal, leído a la americana |
El tipo de la columna |
| Added Conditional Column | is_free |
(price IS NULL) AS is_free |
| Replaced Value1 | null → 0 en price |
COALESCE(price, 0) |
| Extracted Text Before Delimiter | El extremo inferior de owners |
SPLIT_PART(owners, '..', 1) |
| Replaced Value2, Replaced Value3, Changed Type1 | Fuera comas y espacios raros, y luego un número entero | REGEXP_REPLACE(..., '[^0-9]', '', 'g')::bigint |
| Changed Type with Locale1 | release_date como fecha |
TO_DATE(...) |
| Added Conditional Column1 | price_band |
CASE WHEN ... END |
| Filtered Rows | Filas cuyo game es NA eliminadas |
WHERE game IS NOT NULL |
Los nombres de los pasos son los de por defecto
Estos son los nombres que Power Query da a un paso cuando no lo renombras. Los tuyos pueden diferir un poco según la versión y el orden en que hayas hecho los clics. Lo que importa es que sepas leer la lista y decir qué hizo cada línea.
El orden es la lógica¶
Vuelve al paso 3 e intercambia sus dos movimientos. Primero reemplaza null por 0, y después añade is_free.
¿Qué pasa? Todos los juegos son "no gratuitos". Cuando la columna condicional busca null, ya no queda ninguno: has sobrescrito la prueba.
| Orden | price cuando se calcula is_free |
is_free |
|---|---|---|
| Marcar primero, rellenar después | Todavía null en los juegos gratuitos |
true en 3,095 filas |
| Rellenar primero, marcar después | Ya es 0, nunca null |
false en todas las filas |
En una receta grabada, el orden de las líneas es la lógica. SQL tiene la misma regla con otra forma: en games_clean.sql, is_free lee el price original, no el rellenado.
El mismo razonamiento explica el paso 1. Si te lo saltas, ningún precio es null, así que is_free también es false en todas partes.
Un número no es un número: el locale¶
Un locale (configuración regional) es el conjunto de convenciones regionales que un ordenador usa para leer y escribir valores: qué carácter marca los decimales, en qué orden se escribe una fecha, cómo se llaman los meses.
Aquí tienes una frase que parece obviamente cierta: "9.99 es 9.99 en todos los ordenadores". Es falsa cuando el número llega como texto, que es lo que es un CSV.
| El texto del archivo | Leído con English (United States) | Leído con Spanish (Spain) |
|---|---|---|
9.99 |
9.99: el punto es la marca decimal | No es 9.99: el punto es el separador de miles y la coma es la marca decimal |
Nov 16, 2004 |
16 de noviembre de 2004 | Puede fallar: las fechas en español se escriben día, mes, año |
Power Query Desktop lee el texto usando el formato regional de tu Windows. En un PC configurado en español, el texto 9.99 puede convertirse en 999 o en un error. Nada te avisa. La columna simplemente se llena de números equivocados.
Using Locale le dice a la cocina de qué país viene el ingrediente. Este archivo se escribió en Estados Unidos, así que las fechas tienen el aspecto Nov 16, 2004 y los decimales usan punto. Por eso los pasos 2 y 5 usan Change Type → Using Locale... y no un simple Change Type.
Ya has visto este error, desde el otro lado
En Tipos y formatos reparaste números escritos a la española, 1.234,50, para que una base de datos que espera un punto pudiera leerlos. Es el mismo error, en espejo: un número americano leído por un PC español. La regla es una sola: un número escrito como texto tiene nacionalidad, y tienes que conocerla.
Rebobinar y leer el código¶
De vuelta en el editor (Home → Transform data), haz clic en una línea temprana de Applied Steps. La vista previa viaja atrás hasta ese momento: la tabla tal como estaba después de ese paso. Haz clic en la última línea y vuelves al presente. La cruz junto a un paso lo elimina. Ese es tu deshacer.
Ahora abre View → Advanced Editor. Aparece una ventana llena de código.
M es el lenguaje con el que Power Query anota tus pasos. Cada clic que hiciste añadió una línea de M.
La cocina estuvo escribiendo la receta todo el tiempo. Hacer clic no sustituyó al código. Lo escribió por ti.
Cuidado: sin código no significa sin errores
Los errores no desaparecen. Se mudan: al orden de los pasos y al locale. Ambos son invisibles si no lees Applied Steps. Leer esa lista es para Power Query lo que leer el script es para SQL.
¿Power Query o SQL?¶
| Power Query | SQL (SQL Lab) | |
|---|---|---|
| Cómo trabajas | Haces clic en una columna y ves el resultado al instante | Escribes, ejecutas, lees el resultado |
| Dónde está la receta | En Applied Steps, con código M detrás | En el script .sql |
| El original | Intacto. Los pasos se repiten en cada Refresh | Intacto. games se queda como está, games_clean se reconstruye |
| Dónde se ejecuta | En tu PC, dentro del archivo .pbix |
En el servidor de la base de datos |
| Valores vacíos | NA es texto hasta que dices lo contrario |
Ya son NULL tras la subida |
| Qué necesitas | Windows y Power BI Desktop | Un navegador |
Imagina que tu jefe te manda un CSV nuevo cada lunes, con las mismas columnas. ¿Qué herramienta eliges y qué haces cada lunes?
Cualquiera de las dos. En Power Query pulsas Refresh y cada paso se ejecuta de nuevo sobre el archivo nuevo. En SQL vuelves a ejecutar el script. Lo que importa no es clics contra código. Es que la receta exista y se pueda repetir.
La única respuesta equivocada es la tercera cocina: abrir el CSV en una hoja de cálculo y arreglar celdas a mano. No deja ninguna receta. El próximo lunes empiezas de cero, y nadie puede comprobar lo que hiciste.
Cuidado: Power Query no cambió tu CSV
Nunca. Lee el archivo y repite los pasos sobre una copia en memoria. Abre video_games.csv en un editor de texto después de todo tu trabajo: cada NA sigue ahí.
Ideas clave¶
- Power Query es la parte de preparación de datos de Power BI. Trabajas en el Power Query Editor, que se abre con Transform Data.
- Applied Steps registra cada transformación, en orden. Es la receta, y detrás hay código en un lenguaje llamado M.
- Cada clic tiene un gemelo en SQL: Replace Values ↔
COALESCE, Conditional Column ↔CASE WHEN, Text Before Delimiter ↔SPLIT_PART, Filtered Rows ↔WHERE. - El orden de los pasos es la lógica: marca los precios vacíos antes de rellenarlos, o la marca será
falseen todas las filas. - Un número o una fecha escritos como texto tienen un locale. Usa Change Type → Using Locale... para indicar de dónde viene el archivo.
- El perfilado lee solo las primeras 1,000 filas salvo que cambies a todo el conjunto de datos, y
NAes texto hasta que lo reemplazas pornull. - La pregunta no es clics o código. La pregunta es si la receta existe y se puede repetir.
Comprobación rápida¶
1. ¿Qué es la lista de Applied Steps?
- La lista de tablas cargadas en Power BI
- El registro de cada transformación hecha a la tabla, en orden
- La lista de errores encontrados en cada columna
- Una copia del archivo CSV original
Applied Steps es el cuaderno de la pared de la cocina: una línea por transformación, en el orden en que las hiciste. Puedes hacer clic en una línea para ver la tabla en ese momento, o borrar una línea para deshacerla.
2. La lista de un compañero dice: Source, Promoted Headers, Changed Type, Replaced Value, Added Conditional Column. ¿Qué pasos añadió Power Query por su cuenta?
- Ninguno: todos los pasos vienen de un clic
- Solo Source
- Source, Promoted Headers y Changed Type
- Replaced Value y Added Conditional Column
Esos tres aparecen en cuanto se abre el CSV: se lee el archivo, la primera fila pasa a ser los nombres de columna y se adivina un tipo para cada columna. Todo lo que viene después lo hizo la persona.
3. La columna is_free de ese mismo compañero es false para todos los juegos. Elige las dos causas probables.
- Los precios vacíos se reemplazaron por 0 antes de que la columna condicional buscara
null - El texto
NAnunca se reemplazó pornull, así que ningún precio eranull - Power Query no puede crear columnas verdadero/falso
- Un paso anterior modificó el archivo CSV
En ambos casos la columna condicional no encuentra ningún null que marcar. O bien la prueba se sobrescribió demasiado pronto, o bien las letras NA seguían siendo texto normal. El orden de los pasos es la lógica. Y el CSV no se modifica nunca.
4. ¿Por qué la página usa Change Type → Using Locale... para price y no un Change Type normal?
- Porque un Change Type normal borra las filas que no puede convertir
- Porque los precios deben guardarse siempre como texto
- Porque el archivo se escribió con convenciones de EE. UU., y un PC configurado en otra región puede leer el punto de otra forma
- Porque Using Locale hace la conversión más rápida
Un número escrito como texto sigue las convenciones del lugar donde se escribió. En un PC configurado en español, el punto de 9.99 es un separador de miles. Using Locale le dice a Power Query que lea la columna como English (United States), sea cual sea la configuración del PC.
5. Justo después de abrir el archivo, Column quality muestra un porcentaje de valores vacíos para metascore. ¿Por qué no deberías apuntar todavía ese número?
- Porque por defecto se calcula solo con las primeras 1,000 filas, y
NAtodavía cuenta como texto - Porque Column quality solo funciona con columnas numéricas
- Porque Power Query redondea cada porcentaje a la decena más cercana
- Porque el archivo todavía no se ha guardado
El perfilado empieza con las primeras 1,000 filas de un archivo de 26,688: haz clic en el mensaje de la esquina inferior izquierda para pasar a todo el conjunto de datos. Y mientras no lo reemplaces, NA es texto, no un valor vacío.
6. ¿Qué SQL hace lo mismo que Transform → Extract → Text Before Delimiter con el delimitador ..?
-
COALESCE(owners, '..') -
SPLIT_PART(owners, '..', 1) -
WHERE owners IS NOT NULL -
TO_DATE(owners, '..')
Ambos se quedan con el texto anterior al primer ..: de 10,000,000 .. 20,000,000 obtienes el extremo inferior del rango. COALESCE rellena valores vacíos, WHERE filtra filas y TO_DATE convierte texto en fecha.
7. Una tienda te manda un CSV de ventas nuevo cada lunes con las mismas columnas. ¿Qué forma de trabajar hay que evitar?
- Power Query: pulsar Refresh para que los pasos grabados se ejecuten sobre el archivo nuevo
- SQL: volver a ejecutar el mismo script sobre la tabla nueva
- Abrir el CSV en una hoja de cálculo y arreglar las celdas a mano cada semana
- Ninguna: las tres son igual de seguras
Arreglar celdas a mano no deja ninguna receta: nadie puede ver qué se cambió, y el próximo lunes empiezas de cero. Power Query y SQL están bien porque los pasos están escritos y se pueden repetir.
La tabla está limpia, en dos cocinas. Todavía nadie le ha preguntado nada. Siguiente: Estadística exploratoria, donde games_clean por fin responde una pregunta sencilla con una respuesta sorprendente: ¿cuánto cuesta un juego?