Para la preparación de datos se utilizó una base histórica de 2017 a 2025 a la cual se les hace un tratamiento a los datos para preparar la base necesaria para la obtención de las variables deltas para el análisis de elasticidad Este script consolida múltiples archivos de datos (CSV y Excel) relacionados con cemento y concreto, realiza transformaciones específicas y corrige etiquetas de productos.
Estructura del Código
import pandas as pd # Manipulación de datos
import os # Operaciones del sistema de archivos
2. Funciones Principales
leer_archivos()
Propósito: Leer y consolidar archivos de diferentes fuentes preservando formatos de fecha.
Parámetros: Ninguno
Retorna:
union: DataFrame consolidado archivos_leidos: Lista de nombres de archivos procesados Flujo:
Lee archivo principal con manejo explícito de fechas Itera sobre archivos en carpeta SAP Lee según extensión (CSV o Excel) Añade columna Archivo_Origen para trazabilidad Renombra columnas para estandarización Concatena todos los DataFrames convertir_fechas(df)
Propósito: Conversión robusta de columnas de fecha con diagnóstico detallado.
Parámetros:
Retorna: DataFrame con fechas convertidas
Características:
Usa pd.to_datetime con errors='coerce' para manejo seguro Proporciona diagnóstico pre/post conversión Identifica fechas problemáticas 3. Ejecución Principal
Fase 1: Lectura y Consolidación
python
union, archivos_procesados = leer_archivos()
Fase 2: Conversión de Fechas
python
cem['Created On'] = pd.to_datetime(cem['Created On'], format='mixed', dayfirst=True)
cem['Año'] = cem['Created On'].dt.year
cem['Mes'] = cem['Created On'].dt.month
cem['Año-Mes'] = cem['Año'].astype(str) + '-' + cem['Mes'].astype(str)
Se renombran las columnas en los archivos de cierre 2024 y 2025
Renombrar columnas
rename_dict = {
'Period': 'Mes',
'Company Code': 'CoCd',
'Zona.1': 'Product Family',
'Customer': 'Customer Number',
'SKUQty': 'Volumen',
'Total': 'Amount',
'Created on': 'Created On',
'Sales Order': 'Order Number',
'Precio': 'Price',
'Reference document': 'Ref.doc.no'
}
4. Rutas de Archivos
Entradas:
Salida:
Parte 2: Enriquecimiento de Clientes
Descripción General
Este script enriquece el dataset principal de cemento y concreto con información de nombres de clientes a partir de un catálogo maestro, realizando una unión (merge) para agregar razones sociales normalizadas.
🗂️ Estructura del Código
1. Carga de Datasets
Archivo Principal de Datos
python
df = pd.read_csv(r"...\Cemento y Concreto 2025.csv")
Catálogo de Clientes
python
cat_clientes = pd.read_csv(
r"...\BaseClientes 12 ene.csv",
encoding='utf-8' # Especifica codificación para caracteres especiales
)
Contenido: Catálogo maestro de clientes con información normalizada 2. Limpieza y Normalización
Para el DataFrame Principal (df)
python
df['Customer Number'] = df['Customer Number'].astype(str).str.strip()
Conversión: A string para consistencia Limpieza: Elimina espacios en blanco al inicio/final Para el Catálogo de Clientes (cat_clientes)
Columnas Agregadas:
Customer Number agregado: Número de cliente normalizado/consolidado Customer Name agregado: Razón social/nombre de cliente normalizado Tipo de Unión:
how='left': Preserva todos los registros del dataset principal (df) Registros sin coincidencia en el catálogo tendrán NaN en las nuevas columnas 4. Guardado del Resultado
python
df.to_csv(
r"...\Archivos Sap\bases\SAP.csv",
index=False # No incluir índice automático de pandas
)
Limpieza de filiales y exportaciones
Filtrado por Productos Específicos
python
valores_a_buscar = [
'CEMBPC40', 'CEMSPC30', '200TC34', 'CEMSSPC40', '200BC34',
'003B1WS', 'CEMSPC3025', 'CEMBPC30', '250TC34', 'CEMSSPC30',
'MR425C34', 'MR40C34', '150TC34', '250BC34', '065C1WS',
'MOREST', 'MASS03', 'MASS02', '150TC38', 'MR42C34',
'CEMSSPC40Q', 'CEMSPC30PV'
]
sap = sap[sap['Product'].isin(valores_a_buscar)]
Reetiquetado de Productos
python
reemplazos = {
'CEMSPC30PV': 'CEMSPC30',
'CEMSPC3025PV': 'CEMSPC3025',
'MASS0225': 'MASS02',
'MASS0325': 'MASS03'
}
sap['Product'] = sap['Product'].replace(reemplazos)
Selección de Columnas Relevantes
python
columnas_a_mantener = [
"Mes", "Created On", "Product", "Zona", 'Area', "Subsegmento",
'Volumen', 'Customer Name', "Amount", 'Price', "Pestaña",
"Order Number", 'Customer Number', 'Currency key',
'Customer Number agregado', 'Customer Name agregado'
]
nsap = sap.filter(items=columnas_a_mantener)
Creación de Segmentos Comerciales
La base resultante de esta limpieza:
A esta base se le hace una segmentación de los años 2024 y 2025 y una limpieza a las variables ‘Amount’ y ‘Volume’ además de agregar la variable de ‘Cluster’ con el catálogo de clúster construido en la Clusterizacion. Se agrega la presentación PDM de los productos elegidos en el análisis de Pareto Se hace una segmentación de las nueve ciudades validas: 'Chihuahua', 'Delicias', 'Parral', 'Casas Grandes', 'Jimenez', 'Juarez', 'Camargo', 'Ojinaga', 'Cuauhtemoc' El resultado de esta limpieza es la base:
Creación de un df_i para crear varios dataframes por Zona, Presentación, PDM y Clusters
Block y Concreto están a nivel Zona
Cemento a nivel Ciudad
Se genera la variable Precio GCC
Se generan las variables Delta Volumen y Delta Precio
Se guardan las bases intermedias en las locaciones
Se hace un proceso de regresión lineal a cada una de estas bases
Variables de Modelo de Elasticidad Precio OLS
Este código calcula y almacenas métricas de un modelo de regresión lineal OLS (Ordinary Least Squares) para estimar la elasticidad precio de la demanda.
Se está modelando la relación entre precio y volumen de ventas mediante una regresión log-log:
text
ln(Q) = β₀ + β₁ * ln(P) + ε
Donde:
ln(Q): Logaritmo natural del volumen ln(P): Logaritmo natural del precio β₁: Elasticidad precio (coeficiente clave) Elasticidad Precio (Coeficiente del Modelo)
python
df['Elasticidad_Precio_OLS'] = model.params['ln_P']
Qué es: Coeficiente estimado de ln_P en la regresión Bondad de Ajuste del Modelo
python
df['R2_OLS'] = model.rsquared
Qué es: Coeficiente de determinación (R²) Tamaño de Muestra del Modelo
python
df['N_obs_OLS'] = int(model.nobs)
Qué es: Número de observaciones usadas en la regresión Transformaciones Logarítmicas
python
df['ln_Q'] = np.log(df['Volumen'])
df['ln_P'] = np.log(df['Precio_GCC'])
Propósito: Crear variables para modelo log-log Predicciones del Modelo
python
df['ln_Q_hat'] = model.predict(df[['ln_P']])
Qué es: Valores predichos de ln_Q según el modelo Cálculo: ln_Q_hat = β₀ + β₁ * ln_P Comparar con valores reales Pronosticar volumen dado un precio Residuales del Modelo