Este repositorio contiene la resolución de una prueba técnica basada en un dataset de solicitudes de compensaciones/comisiones de clientes (requests.xlsx).
El objetivo principal es limpiar y preparar los datos, realizar un análisis exploratorio y generar algunas visualizaciones básicas.
-
data/requests.xlsx
Fichero original con las solicitudes (239.400 registros y 13 columnas). -
Script / notebook principal donde se realiza:
- Carga y exploración del dataset.
- Limpieza y transformación de datos.
- Análisis exploratorio (EDA).
- Visualizaciones.
-
archivo.xlsx
Fichero resultante tras la limpieza y transformación del dataset original.
-
Exploración inicial de los datos
- Carga del fichero
requests.xlsxconpandas. - Revisión de tipos de datos, valores nulos y estadísticos básicos.
- Identificación de columnas clave:
BookingRequest dateRequested byAuthorized byDepartmentCurrencyAmountReasonReason 2StatusCustomerShortnameCustomerRegionAmount COMGES in EUR
- Carga del fichero
-
Limpieza y estandarización
-
Duplicados
- Identificación de reservas duplicadas por
BookingyAmount:- Ejemplos:
100/1200589,100/1239393.
- Ejemplos:
- Eliminación de duplicados manteniendo la primera aparición.
- Identificación de reservas duplicadas por
-
Renombrado de columnas
- Eliminación de espacios en nombres de columnas para facilidad de uso en código:
Request date→Request_dateAuthorized by→Authorized_byAmount COMGES in EUR→Amount_COMGES_in_EUR- etc.
- Eliminación de espacios en nombres de columnas para facilidad de uso en código:
-
Corrección de nulos en
Authorized_by- Detección de filas con
Authorized_by = NaN. - Revisión por región (
CustomerRegion) para intentar inferir el aprobador. - Al no existir patrón claro, se opta por eliminar esas filas.
- Detección de filas con
-
Corrección de correos electrónicos
- Validación de formato de correo mediante expresión regular.
- Identificación de casos sin
@hotelbeds.com(ej.user69hotelbeds.com). - Aplicación de una función
change_emailpara corregirlos:- Inserción del carácter
@antes dehotelbeds.
- Inserción del carácter
-
Moneda y cambio a EUR
- Revisión de la columna
Currencyy detección de valores erróneos (ej.UDS,CYN,KWR). - Creación de un diccionario de tipos de cambio (
exchange_rates). - Conversión de
Amounta EUR con una funciónconvert_to_eur. - Normalización:
Amountpasa a estar en EUR.Currencyse fuerza a"EUR"en todo el dataset.
- Revisión de la columna
-
Tratamiento de
ReasonyReason_2- Revisión de valores nulos en
Reason:- Detección de casos concretos con cliente
CLIENT113yReason_2 = "CANCELLATION WAIVE". - Se observa que, para este mismo cliente y tipo de
Reason_2, laReasones mayoritariamente"CANCELLATIONS". - Decisión: imputar los
NaNdeReasoncomo"CANCELLATIONS".
- Detección de casos concretos con cliente
- Estandarización de valores en
Reason:- Conversión a formato título (
.str.title()), unificando:"OTHERS"→"Others""BOOKING_OPERATIONAL_ISSUE"→"Booking_Operational_Issue"- etc.
- Conversión a formato título (
- Tratamiento de
Reason_2:- Sustitución de nulos por
"Unknown". - Normalización de texto con
.str.title().
- Sustitución de nulos por
- Revisión de valores nulos en
-
Eliminación de
Amount_COMGES_in_EUR- Detección de 8 valores nulos.
- Decisión: eliminar la columna completa al no ser necesaria tras la conversión de
Amounta EUR.
-
Conversión de tipos
- Conversión de
Request_datea tipodatetime:df['Request_date'] = pd.to_datetime(df['Request_date']).
- Conversión de
-
-
Análisis exploratorio (EDA)
-
Distribución de tipos de cancelación (
Reason)- Conteo de valores y gráfico de barras:
Otherses la categoría dominante (más de 230k registros).- Resto de categorías con volúmenes mucho menores:
Booking_Operational_IssueBooking_Technical_IssueCancellationsRate_ErrorOperational Issues.
- Conteo de valores y gráfico de barras:
-
Distribución de importes (
Amount)- Boxplot para detectar:
- Rango típico de gastos.
- Existencia de outliers (p.ej. importes muy elevados cercanos a 300.000).
- Boxplot para detectar:
-
Cancelaciones por región (
CustomerRegion)- Gráfico de barras:
- Mayor número de solicitudes en
Region 1, seguida deRegion 2yRegion 3. Region 4yRegion 5con menor volumen.
- Mayor número de solicitudes en
- Gráfico de barras:
-
Evolución temporal de solicitudes
- Agrupación por
Request_datey representación en gráfico de líneas:- Picos claros de volumen en determinadas fechas.
- Visión global de la evolución diaria de solicitudes.
- Agrupación por
-
Usuarios que más solicitan (
Requested_by)- Cálculo de frecuencia por correo.
- Top 10 solicitantes:
user23@hotelbeds.comdestaca muy por encima del resto (más de 200k solicitudes).- Resto de usuarios con un número de peticiones muy inferior.
-
- Dataset final: 239.395 registros y 12 columnas completamente limpias, sin valores nulos.
- Moneda unificada en EUR para facilitar comparativas y análisis.
- Correos y motivos (
Reason,Reason_2) estandarizados y listos para modelado o análisis posterior. - Identificación de patrones:
- Dominancia de la categoría
OthersenReason. - Concentración de solicitudes en:
- Determinados usuarios (
Requested_by). - Determinadas regiones (
Region 1yRegion 2).
- Determinados usuarios (
- Picos temporales de solicitudes, útiles para análisis de carga u operativa.
- Dominancia de la categoría
- Python 3.10+ (recomendado)
- Dependencias principales:
pandasnumpyopenpyxlmatplotlibseaborn
- Clonar el repositorio:
git clone <URL_DEL_REPO> cd <NOMBRE_DEL_REPO>- Crear entorno virtual (opcional, pero recomendado):
python -m venv .venvsource .venv/bin/activate# En Windows: .venv\Scripts\activate
Instalar dependencias:
pip install -r requirements.txt
Columnas del dataframe limpio (df):
- Booking (object): identificador de reserva.
- Request_date (datetime64[ns]): fecha de la solicitud.
- Requested_by (object): email del solicitante (formato validado).
- Authorized_by (object): email del aprobador (sin nulos).
- Department (object): departamento (en este caso, siempre "Sales").
- Currency (object): moneda, normalizada a "EUR".
- Amount (float): importe de la solicitud en EUR.
- Reason (object): motivo principal de la solicitud (cancelación, error, etc.).
- Reason_2 (object): motivo detallado / subcategoría.
- Status (object): estado de la solicitud (Applied, Removed, Requested, etc.).
- CustomerShortname (object): identificador abreviado del cliente.
- CustomerRegion (object): región del cliente (Region 1–Region 5).
Autor
- Nombre: Yanelis Serrano Taylor
- Rol: Data Analyst / Full Stack Web
- Contacto: yanelis@adalab.es