¡Bienvenidos, muy buenos días tardes o noches , según donde me leas !
¡Bienvenidos a un emocionante desafío de datos! En este post, exploraremos el fascinante mundo de la limpieza y el modelado de datos utilizando herramientas como Python y PostgreSQL. En el reto número 9, nos enfrentamos a la tarea de transformar datos crudos en una estructura más organizada y comprensible para su análisis.
En el primer capítulo de este desafío, abordamos la exportación de datos desde una hoja de Excel. Sin embargo, nos dimos cuenta de que necesitábamos una mayor especificidad en la selección de hojas. Así que, hoy, realizaremos un ajuste en nuestro código Python para abordar este problema sin limpiar los datos por completo.
Limpieza de datos: Un paso esencial en cualquier proyecto de datos es la limpieza. En esta fase, revisaremos cada columna y determinaremos qué datos son relevantes para nuestro análisis. En este caso, nos centraremos en la primera columna. Aunque esto es solo el comienzo, ya que más adelante veremos cómo limpiar los datos en PostgreSQL.
Pero antes de sumergirnos en la limpieza, definiremos qué es el modelado de datos. El modelado de datos es un proceso fundamental en la gestión y análisis de datos. Implica la creación de representaciones estructuradas y organizadas de la información, lo que facilita su comprensión, gestión y análisis.
Algunos conceptos clave relacionados con el modelado de datos que exploraremos incluyen:
- Representación Abstraída: Simplificamos los datos del mundo real, capturando lo esencial sin detalles innecesarios.
- Modelo Conceptual: Creamos un modelo que se enfoca en definir entidades, relaciones y atributos sin entrar en detalles técnicos.
- Modelo Lógico: Desarrollamos un modelo más detallado, definiendo tablas, columnas y relaciones.
- Modelo Físico: Representamos la implementación real en una base de datos específica.
- Normalización: Proceso para eliminar redundancias y mejorar la integridad de los datos.
- Integridad de Datos: Definimos reglas y restricciones para garantizar la precisión y consistencia de los datos.
Y esto es solo el principio. A medida que avanzamos, exploraremos más a fondo cómo realizar un unpivot en las columnas de enfermedades para transformar los datos en un formato tabular más adecuado para análisis y visualización.
Además, crearemos nuestro modelo conceptual y hablaremos de las herramientas que utilizamos para desarrollar mapas conceptuales, como Lucidchart y Draw.io.
En la siguiente fase, nos sumergiremos en la limpieza de datos en PostgreSQL. Exploraremos cómo eliminar duplicados, gestionar valores nulos y estandarizar los datos para que sigan un formato específico.
Uno de los momentos clave es cuando realizamos un unpivot en las columnas de enfermedades, lo que simplifica significativamente la manipulación y el análisis de datos cuando tenemos múltiples columnas con datos similares.
Pero eso no es todo. También exploraremos cómo identificar la necesidad de crear nuevas entidades durante el proceso de limpieza y cómo actualizar nuestro modelo conceptual en consecuencia.
Limpieza de datos: Identificar y revisar cada columna. Determinar qué datos utilizaremos y cuáles no. En este caso, usaremos específicamente los datos de la primera columna. Realizaremos un leve ajuste en el código creado en Python. ¿Por qué en esta fase selecciono la limpieza de datos en PostgreSQL? Porque la idea es poner en práctica diferentes tecnologías y lenguajes en un mismo reto.
Antes de empezar, definiremos qué es un modelado de datos.
El modelado de datos es un proceso fundamental en la gestión y análisis de datos que implica la creación de representaciones estructuradas y organizadas de la información. El objetivo principal del modelado de datos es capturar y definir la estructura, relaciones y características de los datos de una manera que facilite su comprensión, gestión, análisis y uso en aplicaciones de software, informes, visualizaciones y toma de decisiones. A continuación, te explicaré algunos conceptos clave relacionados con el modelado de datos:
Representación Abstraída: En el modelado de datos, los datos del mundo real se representan de manera abstraída y simplificada. Esto significa que se capturan los aspectos esenciales y relevantes de los datos sin incluir detalles innecesarios.
Modelo Conceptual: En las primeras etapas del modelado de datos, se crea un modelo conceptual que se enfoca en definir las entidades, relaciones y atributos clave sin entrar en detalles técnicos de implementación. Este modelo se centra en la lógica y la estructura de los datos en lugar de la tecnología subyacente.
Modelo Lógico: El modelo lógico se desarrolla a partir del modelo conceptual y agrega más detalles técnicos. Aquí se definen las tablas, columnas, restricciones y relaciones en función de las necesidades del sistema de gestión de bases de datos que se utilizará para almacenar los datos.
Modelo Físico: El modelo físico representa la implementación real de los datos en un sistema de base de datos específico. En esta etapa, se consideran aspectos como el tipo de base de datos, el rendimiento y la optimización de consultas, y se crean estructuras de tablas concretas.
Relaciones y Cardinalidad: El modelado de datos define las relaciones entre las entidades (tablas) y especifica la cardinalidad de estas relaciones. Por ejemplo, una entidad «Cliente» puede tener una relación «realiza compras» con la entidad «Pedido», y la cardinalidad podría ser «un cliente puede realizar varios pedidos».
Normalización: La normalización es un proceso que se aplica en el modelado de datos para eliminar redundancias y mejorar la integridad de los datos. Esto implica dividir las tablas en estructuras más pequeñas y relacionadas de manera lógica.
Integridad de Datos: El modelado de datos también incluye la definición de reglas y restricciones de integridad de datos para garantizar que los datos sean precisos y consistentes.
Documentación: El modelado de datos suele ir acompañado de documentación detallada que describe la estructura, las relaciones y las reglas de los datos. Esta documentación es valiosa para los desarrolladores, analistas y usuarios finales que trabajan con los datos.
Link donde puedes encontrar más información
Ahora que hemos definido qué es un modelo de datos, pasemos a validar específicamente y visualizar en nuestra tabla de aterrizaje o stage cómo están nuestros datos en este momento.
Como vemos, con un simple «select * from reto_9.stage», ahora teniendo en cuenta que solo tenemos este tipo de información, veamos qué columnas tenemos antes de crear nuestro modelo conceptual. Crearemos los procesos de validación.
Código de PostgreSQL básico para la limpieza de datos.
Teniendo claro la hoja de datos exportada y en la tabla stage, que será una tabla base para luego crear nuestro modelo conceptual, recordemos que para el modelo conceptual, debemos identificar cuáles son las entidades, es decir, qué columnas formarán nuestras tablas dimensionales y cómo se relacionarán entre ellas. Solo en esta fase deseamos esto (claro, aquí tenemos que analizar mucho más).
Tenemos las primeras dos columnas con país y código país, esto a simple vista es una entidad, es un dato categórico y brilla a la vista indicando que debe ser una entidad aparte para mi análisis de datos. (Imagen 2)
También tenemos el año, lo que significa que tenemos una granularidad en lo que se refiere al tiempo solo hasta el año. En mi caso, me gusta más otra entidad.
Revisando más a detalle, identificamos que las enfermedades en este reto de datos están en las columnas. Aquí debemos analizar la dinamización de las columnas con encabezado de enfermedad. Dirás, ¿por qué? Procedo a explicar detalladamente el por qué debemos realizar esto:
Si procedemos con una operación de unpivot en las columnas que representan las enfermedades en tu conjunto de datos, transformaremos la estructura de los datos para que sea más adecuada para el análisis y la visualización en Power BI (que es nuestra herramienta en la cual decidimos visualizar datos porque es la mejor, jejeje, le viene de maravilla este tipo de modelo de datos) u otras herramientas similares. A continuación, te explico qué sucedería si realizas esta operación de manera más visual:
Tomemos como ejemplo solo 4 columnas y pocas filas:
Pais | Año | Meningitis | Enfermedad de Alzheimer | ...
Afganistan | 1990 | 2159 | 1116 | ...
Afganistan | 1991 | 2218 | 1136 | ...
Afganistan | 1992 | 2475 | 1162 | ...
Después de realizar una operación de unpivot en las columnas que representan las enfermedades, quedaría de esta manera en formato TABULAR:
Pais | Año | Enfermedad | Valor
Afganistan | 1990 | Meningitis | 2159
Afganistan | 1990 | Enfermedad de Alzheimer | 1116
Afganistan | 1991 | Meningitis | 2218
Afganistan | 1991 | Enfermedad de Alzheimer | 1136
Afganistan | 1992 | Meningitis | 2475
Afganistan | 1992 | Enfermedad de Alzheimer | 1162
En este nuevo formato, tienes una sola columna llamada «Enfermedad» que contiene los nombres de las enfermedades y otra columna llamada «Valor» que contiene los valores asociados a cada enfermedad para cada país y año. Esto facilita la creación de informes y visualizaciones en Power BI, ya que puedes usar la columna «Enfermedad» como una dimensión para segmentar tus datos y la columna «Valor» como una medida para realizar cálculos y representar los valores de las enfermedades.
Realizar un unpivot es sencillamente genial porque puede simplificar significativamente la manipulación y el análisis de datos cuando tienes múltiples columnas con datos similares en una tabla.
Luego de esta explicación, identificamos varios cambios iniciales que podemos ir desarrollando. Este es solo el comienzo, un pequeño vistazo. No hemos limpiado aún. OJO, dentro de unos minutos vamos a ello. Es solo un vistazo para empezar a focalizar cómo quedarán nuestras entidades y la relación entre ellas (Modelado conceptual). Entonces, creemos el modelo conceptual.
¿Qué herramienta me gusta para desarrollar este tipo de mapas conceptuales? Bueno, uso dos, o más bien me gustan dos. Lucidchart, aquí dejo el enlace, y la que usaremos hoy es Draw.io (versión web). Vamos, que si no, en papel y lápiz, que también me gusta mucho, o en un Excel. Lo importante es entender la lógica y dónde plasmar esta lógica. Te menciono primero los enlaces que uso, porque puedes desear de una vez documentar este proceso, que es mi recomendación.
Empecemos a crear nuestro modelo conceptual
Identificamos la entidad que tendrá país y código país, ¿verdad? Entonces, tenemos nuestra entidad país. (Imagen 4)
Continuamos y logramos ver que tenemos la entidad año. (Imagen 5)
Por último, tendríamos la entidad o trabajes indicadores de salud. (Imagen 6)
Ahora, en esta fase, debemos ver solo con quién se relacionarían, es decir, qué entidad se relacionará con qué entidad, nada más. Esto (Imagen 7)
Teniendo claro esta fase básica y nuestro modelo conceptual pre-listo, vamos a limpiar los datos de manera eficiente…
Aquí comenzamos con la limpieza y transformación necesaria para nuestros datos.
Paso 1: Eliminación de Datos Duplicados
Primero, verificamos si hay filas duplicadas en el conjunto de datos y las eliminamos para evitar distorsiones en los resultados. Para identificar los duplicados, creamos una consulta que utiliza Common Table Expressions (CTE).
Una Common Table Expression (CTE) es una construcción en SQL que permite definir una tabla temporal dentro de una consulta. Esta tabla temporal se puede utilizar como una parte integral de la consulta principal. Las CTE son especialmente útiles cuando se necesita realizar una operación compleja en una consulta que involucra referencias recursivas, operaciones de ventana o simplemente cuando se quiere hacer que la consulta sea más legible y modular.
Dentro de ellas, utilizamos una función de ventana extraordinaria llamada Common Table Expression (CTE) «CTE». Aquí está el resumen rápido de cómo funciona:
WITH CTE AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY "Pais", "Codigo Pais", "Año" ORDER BY "Pais", "Codigo Pais", "Año") AS RowNum
FROM reto_9.stage
)
En este código SQL, creamos una CTE llamada «CTE» que realiza lo siguiente:
- La consulta SELECT * selecciona todas las columnas de la tabla «reto_9.stage».
- La cláusula ROW_NUMBER() se utiliza para asignar un número de fila a cada fila en función de la partición definida por las columnas «Pais», «Codigo Pais» y «Año». Las filas se ordenan dentro de cada partición en función de esas mismas columnas. El número de fila se almacena en la columna calculada «RowNum».
Luego, seleccionamos las filas con RowNum igual a 2 para identificar duplicados:
SELECT *
FROM CTE
WHERE RowNum = 2
Esta parte del código selecciona todas las filas de la CTE «CTE» donde el valor de la columna «RowNum» es igual a 2. En otras palabras, estamos seleccionando la segunda fila de cada conjunto de filas que tienen la misma combinación de valores en las columnas «Pais», «Codigo Pais» y «Año».
Imagen 8:
En este caso, no tenemos filas duplicadas bajo estas tres columnas («Pais», «Codigo Pais» y «Año») porque solo seleccionamos estas tres columnas específicamente. En la lógica, solo tenemos los datos de las enfermedades de cada país por año.
Luego, procedemos a demostrar cómo funcionaría si hubiera datos duplicados. Ejecutamos una consulta para insertar datos duplicados y luego volvemos a ejecutar la consulta para identificar los duplicados.
Imagen 9:
En la imagen 9, puedes ver que hemos insertado datos duplicados y la consulta identifica correctamente los duplicados.
A continuación, creamos la consulta para eliminar solo el dato duplicado, preservando el original.
Imagen 11:
Voy a explicar el código:
Este código SQL se creó para eliminar filas duplicadas de una tabla llamada reto_9.stage
basadas en las columnas «Pais», «Codigo Pais» y «Año». Aquí está la explicación detallada línea por línea:
WITH Duplicates AS ( ... )
: Esta es una cláusulaWITH
que se utiliza para crear una tabla temporal llamada «Duplicates». Esta tabla temporal contendrá todas las combinaciones únicas de «Pais», «Codigo Pais» y «Año» que tienen más de una fila duplicada en la tabla originalreto_9.stage
. En otras palabras, esta parte del código identifica las combinaciones de «Pais», «Codigo Pais» y «Año» que están duplicadas.SELECT "Pais", "Codigo Pais", "Año" FROM reto_9.stage GROUP BY "Pais", "Codigo Pais", "Año" HAVING COUNT(*) > 1
: Esta es la consulta que se utiliza para crear la tabla temporal «Duplicates». Se seleccionan las columnas «Pais», «Codigo Pais» y «Año» de la tablareto_9.stage
y se agrupan por estas columnas. La cláusulaGROUP BY
agrupa las filas con las mismas combinaciones de valores en esas columnas. Luego, la cláusulaHAVING
se utiliza para filtrar solo las combinaciones que tienen más de una fila duplicada. Estas combinaciones duplicadas se almacenan en la tabla «Duplicates».DELETE FROM reto_9.stage WHERE ...
: Esta es la declaración de eliminación que se utilizará para eliminar las filas duplicadas de la tablareto_9.stage
.WHERE ("Pais", "Codigo Pais", "Año") IN ( ... )
: Esta cláusulaWHERE
se utiliza para especificar las filas que se eliminarán de la tablareto_9.stage
. Se eliminarán todas las filas donde las combinaciones de «Pais», «Codigo Pais» y «Año» estén presentes en la tabla temporal «Duplicates». En otras palabras, esto selecciona todas las filas que se identificaron previamente como duplicadas.AND ctid NOT IN ( ... )
: Esta cláusulaAND
se utiliza para evitar que se eliminen todas las filas duplicadas. Solo se mantendrá una de las filas duplicadas, y eso se logra mediante el uso dectid
, que es un identificador único para cada fila en una tabla. La subconsulta en esta cláusula selecciona elctid
más bajo (es decir, el primero en aparecer) de cada grupo de filas duplicadas en la tablareto_9.stage
. Las filas conctid
más bajo no se eliminarán, mientras que las demás serán eliminadas.
Este código primero identifica las combinaciones de «Pais», «Codigo Pais» y «Año» que están duplicadas en la tabla reto_9.stage
, las almacena en una tabla temporal llamada «Duplicates» y luego elimina todas las filas duplicadas de la tabla original, conservando solo una fila de cada conjunto duplicado.
Ahora que tenemos el conjunto de datos sin duplicados, creamos una consulta para encontrar valores nulos o faltantes en cada columna. La consulta que creamos es la siguiente:
SELECT *
FROM reto_9.stage
WHERE
"Pais" IS NULL OR
"Codigo Pais" IS NULL OR
"Año" IS NULL OR
"Meningitis" IS NULL OR
"Enfermedad de Alzheimer y otras demencias" IS NULL OR
"Enfermedad de Parkinson" IS NULL OR
"Deficiencias nutricionales" IS NULL OR
"Malaria" IS NULL OR
"Ahogo/Asfixia" IS NULL OR
"Violencia interpersonal" IS NULL OR
"Trastornos maternos" IS NULL OR
"HIV/SIDA" IS NULL OR
"Trastornos por consumo de drogas" IS NULL OR
"Tuberculosis" IS NULL OR
"Enfermedades cardiovasculares" IS NULL OR
"Infecciones respiratorias bajas" IS NULL OR
"Trastornos neonatales" IS NULL OR
"Trastornos por consumo de alcohol" IS NULL OR
"Autolesiones" IS NULL OR
"Exposición a las fuerzas de la naturaleza" IS NULL OR
"Enfermedades diarreicas" IS NULL OR
"Exposición al calor y al frío ambiental" IS NULL OR
"Neoplasias" IS NULL OR
"Conflicto y terrorismo" IS NULL OR
"Diabetes mellitus" IS NULL OR
"Enfermedad renal cronica" IS NULL OR
"Envenenamientos" IS NULL OR
"Desnutrición proteico-energética" IS NULL OR
"Lesiones en la carretera" IS NULL OR
"Enfermedades respiratorias cronicas" IS NULL OR
"Cirrosis y otras enfermedades crónicas del hígado" IS NULL OR
"Enfermedades digestivas" IS NULL OR
"Fuego, calor y sustancias calientes" IS NULL OR
"Hepatitis aguda" IS NULL;
Imagen 12:
En esta consulta, efectivamente encontramos valores nulos en la segunda columna llamada «Codigo Pais». Sin embargo, al revisar más detenidamente, identificamos la necesidad de realizar una limpieza adicional.
Pasamos a filtrar solo los valores nulos, ya que en la columna «Pais» tenemos una oportunidad de limpieza de datos muy buena. Resulta que algunos valores que deberían ser países son, en realidad, regiones. Esto no es deseable en una columna de tipo país, por lo que esto entra en la fase de limpieza de datos llamada «Estandarización de Datos». Aquí es donde puedes estandarizar los datos si es necesario para que sigan un formato específico, como nombres de países o códigos de país.
Imagen 13:
Como se puede ver en la imagen 13, tenemos valores nulos en los registros de la columna «Pais» que en realidad no son países. Sin embargo, al revisar más a detalle, nos damos cuenta de que no solo queremos eliminar los registros con valores nulos en la columna «Codigo Pais», sino que también debemos tener cuidado al eliminar países como Escocia, Gales, el norte de Irlanda e Inglaterra. Es importante recordar que el Reino Unido está compuesto por varias naciones, y eliminarlas podría no ser apropiado dependiendo del análisis que desees realizar.
Por lo tanto, antes de eliminar todos los registros nulos, debemos decidir si deseamos realizar el análisis con solo el Reino Unido como entidad única o si deseamos mantener cada país por separado. Es esencial calcular el volumen de estos y ver si hay variaciones significativas en el volumen de defunciones por enfermedad y país.
Para llevar a cabo esta validación, realizaremos otro paso llamado «Gestión del Control de Datos en Formato Tabular», que implica una transformación de datos similar al unpivot que vimos anteriormente.
Veamos cómo hacer un unpivot columns en PostgreSQL para nuestro formato tabular. La consulta que deseamos es agrupar las enfermedades dentro de una columna llamada «Enfermedad» y los valores en una columna llamada «Valores». Esto reduce el número de columnas de 6,849 a 212,040, lo cual es fundamental ya que facilita la agregación, filtrado y análisis de los datos.
Procedo a explicar el código:
SELECT "Pais", "Codigo Pais", "Año"
:- Esta parte del código selecciona las columnas «Pais», «Codigo Pais» y «Año» de la tabla «reto_9.stage». Estas columnas se mantienen en el resultado final sin cambios.
unnest(array[...]) AS "Enfermedad"
:- Aquí estamos utilizando la función
unnest(array[...])
para crear una lista de enfermedades a partir de las columnas relacionadas con enfermedades. La lista completa de enfermedades se enumera en esta parte del código, y cada una se incluye en un array. - La función
unnest
toma ese array y lo «despliega» en una lista de valores separados por comas. Esto es lo que crea la columna «Enfermedad» en el resultado final. Cada fila en esta columna contendrá el nombre de una enfermedad. - El alias «Enfermedad» se utiliza para nombrar esta nueva columna.
- Aquí estamos utilizando la función
unnest(array[...]) AS "Valor"
:- Similar a la parte anterior, aquí estamos creando otra lista utilizando
unnest(array[...])
. Esta lista contiene los valores correspondientes a cada enfermedad. - Cada valor en esta lista está relacionado con la enfermedad en la misma posición en la lista «Enfermedad». Por ejemplo, si «Meningitis» tiene un valor de 100 en una fila, ese valor se incluirá en la columna «Valor» junto con la etiqueta «Meningitis» en la columna «Enfermedad».
- El alias «Valor» se utiliza para nombrar esta nueva columna.
- Similar a la parte anterior, aquí estamos creando otra lista utilizando
El resultado final será una tabla donde las columnas «Pais», «Codigo Pais» y «Año» se mantienen sin cambios, pero las columnas de enfermedades se han convertido en dos columnas: «Enfermedad» y «Valor». Cada fila representa una combinación de país, código de país y año junto con una enfermedad específica y su valor correspondiente.
Ahora bien, como tenemos esta consulta en este formato, podemos validar el paso anterior si borrando todos los registros nulos de la tabla o eliminando los nulos excepto los países que pertenecen al Reino Unido.
Hagamos este sumatorio creando una tabla temporal con la consulta en formato tabular. Calculemos primero el total de la columna «Valores» solo para el Reino Unido, el cual incluye a Gales, Escocia, Irlanda del Norte e Inglaterra. La consulta será la siguiente:
Procedemos a realizar una revisión de datos básica y exhaustiva, como se muestra en la imagen 16.
Posterior a ello, creamos la consulta primero para el Reino Unido:
-- Sumando los datos de United Kingdom
SELECT SUM("Valor"::integer) FROM tabla_temporal
WHERE "Pais" = 'United Kingdom';
Lo cual nos da un total de 17,281,573, como se muestra en la imagen 17.
Luego, realizamos la consulta con el resto de países:
-- Sumando los países
SELECT SUM("Valor"::integer) FROM tabla_temporal
WHERE "Pais" IN ('England','Scotland','Wales','Northern Ireland');
Lo cual también nos devuelve 17,281,573, como se muestra en la imagen 18
La diferencia es de solo 27 registros. Por comodidad, seleccionaré quitar todos los registros nulos.
Ahora procedemos a eliminar los nulos. En este caso, realizamos la consulta para su eliminación, como se muestra en la imagen 19:
DELETE FROM reto_9.stage
WHERE "Codigo Pais" IS NULL;
Antes de continuar, es interesante notar que hemos encontrado algo muy interesante. Hemos identificado otra entidad después de realizar la operación unnest. Esto se debe a que tenemos otro dato categórico que se ha multiplicado y se ha convertido en tabular. Por lo tanto, lo mejor será crearlo como una entidad y modificar nuestro modelo conceptual, como se muestra en la imagen 20.
Con esta limpieza y transformación, procedemos a crear la tabla. Realizamos un paso importante en la creación de nuestro modelo lógico. En el modelo lógico, identificamos por qué campo se cruzarán las tablas, y añadimos atributos a las entidades.
Modelo lógico
Regresamos a nuestro diseñador de modelos, draw.io, para crearlo. Ahora, nuestro modelo lógico está tomando la forma de un modelo de tipo estrella o dimensional. Esto es indicativo de que estamos siguiendo el camino correcto, ya que podemos observar que las tres tablas principales orbitan alrededor de una tabla con campos aditivos, calculados y con llaves foráneas, lo que resulta en muchas filas pero pocas columnas. Las dimensiones o entidades orbitan alrededor con pocas filas, como debe ser. Esto se resalta en el siguiente artículo de Power BI, cuyo enlace comparto: enlace. Puedes ver más detalles en la imagen 21.
Luego, procedemos a crear una tabla temporal limpia sobre la cual comenzaremos el modelo físico. Este modelo físico se trabaja directamente en la base de datos que seleccionamos.
Pasamos a crear nuestra primera Dimensión, que será la de país, como se muestra en la imagen 22. El código para esta dimensión es el siguiente:
-- Creando consulta
SELECT DISTINCT("Pais"), "Codigo Pais" FROM tabla_temporal_limpia;
— Creamos la tabla Dim_PaisCREATE TABLE Dim_Pais (
Id_pais serial PRIMARY KEY,
Pais varchar(255),
Codigo_pais char(10)
);— Creando insert
INSERT INTO Dim_Pais (Pais, Codigo_pais)
SELECT DISTINCT(«Pais»), «Codigo Pais» FROM tabla_temporal_limpia;SELECT * FROM Dim_Pais;
Procedemos a crear la tabla Dim_Anio como se muestra en la imagen 23:
-- Creando consulta para el año
SELECT DISTINCT("Año") FROM tabla_temporal_limpia;
— Creando la tabla Dim_AnioCREATE TABLE Dim_Anio (
Id_anio serial PRIMARY KEY,
Anio int
);— Insertando datos
INSERT INTO Dim_Anio (Anio)
SELECT DISTINCT(«Año»::integer) FROM tabla_temporal_limpia;— Verificar la tabla
SELECT * FROM Dim_Anio;
Ahora creamos la dimensión de enfermedades. La consulta para esta dimensión y la creación de la tabla se muestran en la imagen 24:
-- Consulta para la dimensión enfermedades
SELECT DISTINCT("Enfermedad") FROM tabla_temporal_limpia;
— Creando tabla Dim_EnfermedadCREATE TABLE Dim_enfermedad (
Id_Enfermedad serial PRIMARY KEY,
Enfermedad varchar(255)
);— Insertando datos
INSERT INTO Dim_enfermedad (Enfermedad)
SELECT DISTINCT(«Enfermedad») FROM tabla_temporal_limpia;SELECT * FROM Dim_enfermedad;
Luego, pasamos a crear la tabla de hechos con varios left join. La consulta para esto se muestra en la imagen 25:
SELECT a."Valor"::integer, b.Id_pais, c.Id_Anio, d.id_enfermedad
FROM tabla_temporal_limpia AS a
LEFT JOIN Dim_Pais AS b
ON a."Pais" = b.Pais
LEFT JOIN Dim_Anio AS c
ON a."Año"::int = c.Anio
LEFT JOIN Dim_Enfermedad AS d
ON a."Enfermedad" = d.Enfermedad;
Luego, creamos la tabla de hechos con las llaves foráneas correspondientes y los tipos de datos adecuados, como se muestra en la imagen 26:
-- Creamos la tabla Fact_Indicadores_Salud
CREATE TABLE Fact_Indicadores_Salud (
Valor int,
Id_pais int,
Id_Anio int,
id_enfermedad int,
FOREIGN KEY (Id_pais) REFERENCES Dim_Pais (Id_pais),
FOREIGN KEY (Id_Anio) REFERENCES Dim_Anio (Id_Anio),
FOREIGN KEY (id_enfermedad) REFERENCES Dim_enfermedad (id_enfermedad)
);
Luego, procedemos a crear la consulta para alimentar la tabla de hechos. La consulta se muestra en la imagen 27:
INSERT INTO Fact_Indicadores_Salud (Valor, Id_pais, Id_Anio, id_enfermedad)
SELECT a."Valor"::integer, b.Id_pais, c.Id_Anio, d.id_enfermedad
FROM tabla_temporal_limpia AS a
LEFT JOIN Dim_Pais AS b
ON a."Pais" = b.Pais
LEFT JOIN Dim_Anio AS c
ON a."Año"::int = c.Anio
LEFT JOIN Dim_Enfermedad AS d
ON a."Enfermedad" = d.Enfermedad;
SELECT * FROM Fact_Indicadores_Salud;Con todos estos pasos, hemos visto cómo crear un modelo de datos en PostgreSQL, realizar limpieza de datos y crear consultas de diferentes tipos, desde básicas hasta avanzadas.
Todo el código utilizado :
https://github.com/vicente2121/Modeldado_de_datos_reto9.git
Para cerrar ya y dar una pequeñas conclusiones diria que en este desafío «todo en uno» sobre el reto de datos número 9, hemos recorrido un emocionante viaje a través del proceso completo de preparación y modelado de datos. Desde la exportación de datos de una hoja de Excel hasta la creación de un modelo de datos en PostgreSQL, hemos abordado cada fase de manera estructurada y eficiente.
Comenzamos por identificar la necesidad de una limpieza de datos específica, centrándonos en seleccionar la hoja adecuada y examinando cada columna para determinar qué datos serían relevantes para nuestro análisis. Exploramos conceptos clave relacionados con el modelado de datos, desde la representación abstraída hasta la normalización y la integridad de los datos.
Luego, nos sumergimos en el mundo de PostgreSQL, donde realizamos operaciones importantes como la eliminación de datos duplicados y la identificación de valores nulos. Destacamos la importancia de la estandarización de datos y exploramos cómo realizar una operación de unpivot en columnas para mejorar la estructura de nuestros datos.
Continuamos con la creación de un modelo conceptual y avanzamos hacia el modelo lógico y físico, definiendo las tablas dimensionales y la tabla de hechos. Utilizamos consultas SQL para alimentar estas tablas con datos limpios y relacionados.
En última instancia, nuestro modelo de datos resultante se ajustó a un diseño de tipo estrella o dimensional, ideal para análisis de datos en herramientas como Power BI. Hemos demostrado cómo todos estos pasos son cruciales para convertir datos crudos en información valiosa y lista para la toma de decisiones.
Este desafío no solo nos brindó la oportunidad de adentrarnos en el mundo de la gestión de datos y bases de datos, sino que también destacó la importancia de la limpieza, transformación y modelado adecuados para aprovechar al máximo la información contenida en los datos. En resumen, hemos demostrado que la preparación adecuada de datos es el cimiento fundamental para cualquier análisis de datos exitoso.
Business Intelligence Technical.
Perfil linkedin
Excelente !!
Hola Silvina, es todo un honor para mi que sea de tu agrado este contenido, muchas gracias por tus palabras y con mucha energía vamos que vamooos!.