GasBu es una aplicación web y móvil para iOS y Android que muestra los precios de los carburantes de cada gasolinera y las incidencias de tráfico oficiales de la Dirección General de Tráfico, del Servei Català de Trànsit y de la Dirección de Tráfico del Gobierno Vasco, junto a los datos oficiales de otros seis países: Francia, Chequia, Austria, Alemania – Baden-Wurtemberg, Croacia y Polonia.
La aplicación web cuenta con las siguientes funcionalidades de acceso libre y gratuito y sin registro previo:
- Precios de los carburantes de todas las gasolineras cercanas.
- Detalle de cada gasolinera: precios actuales, horario, tendencia de precios de los últimos 7 días y coste del depósito lleno.
- Mapa de incidencias de tráfico oficiales: cortes, accidentes, obstáculos, obras y restricciones.
- Listado de las incidencias registradas por cada provincia.
- Zonas de bajas emisiones.
- Las siguientes funcionalidades son de uso limitado:
- Gasolineras favoritas: hasta 3.
- Registro de repostajes y gastos del vehículo: historial de los últimos 30 días.
- Actualizar gasolineras al mover el mapa: 12 veces al día.
- Notificaciones de bajadas de precio y de incidencias de tráfico: 3 cada 7 días.
- Cálculo de desvíos para evitar una incidencia: 10 al mes.
- Planificador de ruta con paradas para repostar: actualmente sin límite (fase beta); después, 1 plan al mes.
La versión para móvil añade a las funcionalidades anteriores, las siguientes:
- Gratuitas:
- Incidencias alrededor del usuario y aviso de corte en la carretera por la que circula y en el planificador de rutas.
- Integración con CarPlay y Android Auto.
- De pago mediante suscripción opcional, mensual o anual:
- Búsqueda por dirección o ciudad.
- Favoritas, historial de repostajes y gastos, mapa, notificaciones, desvíos y planes de ruta sin límites.
Las tres fuentes de datos españolas se indican tanto en la web como en las aplicaciones móviles y sus datos se actualizan cada pocos minutos.
Utiliza el estándar europeo DATEX II para mostrar los códigos de las incidencias: tipo, causa, sentido, gravedad, que son traducidos a 12 idiomas, salvo el texto libre de la fuente que se muestra sin modificar, de forma que un conductor extranjero ve los cortes de la red española en su propio idioma.
MisGasolineras.es es un comparador gratuito y sin publicidad de precios de carburantes en España, construido sobre los datos abiertos de precios en estaciones de servicio del Ministerio para la Transición Ecológica y el Reto Demográfico, con actualización diaria.
Facilita información sobre:
- Precios de los carburantes por municipio (más de 4.000), provincia y marca.
- Precios de AdBlue y GLP por municipio.
- Gasolineras baratas a lo largo de 450 rutas por carretera con plan de paradas.
- Informe semanal e histórico de precios.
- Canal de Telegram con el resumen de cada mañana.
Las series agregadas se ofrecen a su vez como datos abiertos bajo licencia CC BY 4.0.
Observatorio de precios de la calefacción reúne series históricas del precio de todos los combustibles de calefacción y los convierte a una misma unidad, euros por kilovatio hora de calor útil, para poder compararlos: gasóleo, gas natural, butano, propano, electricidad, pellet, hueso de aceituna, astilla y leña. El histórico del gasóleo arranca en 2005 y el del butano en 1994.
Todo se construye reutilizando datos abiertos: el Boletín Petrolero semanal de la Comisión Europea, Eurostat, la CNMC, el INE y Red Eléctrica. Las series se recogen y validan solas todos los días, cada cifra se publica con su fuente, su licencia y su fecha, y las que lo permiten se pueden descargar en CSV o incrustar como gráfico en otra web. Lo que una fuente no autoriza a redistribuir se indica y no se redistribuye.
Incluye además una sección de precios industriales para fabricantes y distribuidores del sector: índices de precios de fábrica del vidrio, la siderurgia, las estufas, los radiadores y los aislantes, junto a las materias primas del propio vitrocerámico (litio, sosa, sílice, alúmina, titanio y circonio) a partir de las estadísticas de comercio exterior de la Unión Europea.
Esta aplicación web es una sección abierta y gratuita del comercio electrónico español Cristales para Chimeneas, especializado en vidrio vitrocerámico cortado a medida para chimeneas, estufas e insertos, con venta en España, Francia, Italia, Alemania y Portugal.
Motavia es una aplicación web para consultar y comparar precios de carburantes en España de forma rápida, clara y sin anuncios, ofreciendo al usuario diversas funcionalidades:
- Explorar gasolineras sobre un mapa.
- Ordenar por precio.
- Filtrar por combustible y apertura.
- Buscar por provincias y municipios.
- Consultar la ficha de cada estación.
- Guardar estaciones favoritas directamente en el dispositivo, sin necesidad de crear una cuenta.
También incorpora una sección de Evolución con histórico de precios por estación, municipio y provincia, para ver cómo han cambiado los precios durante los últimos 90 días y qué estaciones están impulsando las principales subidas o bajadas.
La aplicación reutiliza datos abiertos publicados por el Ministerio para la Transición Ecológica y el Reto Demográfico (MITECO). Los datos se procesan y actualizan automáticamente de forma periódica para ofrecer una consulta sencilla de la información oficial.
La aplicación es estática, gratuita y respetuosa con la privacidad: no contiene publicidad, no requiere registro y no utiliza sistemas de rastreo de usuarios. También puede instalarse en dispositivos compatibles como aplicación web progresiva (PWA).
LlenoBarato es una aplicación web que reutiliza los datos abiertos del Ministerio para mostrar y comparar los precios de los carburantes en las gasolineras de España.
La información se actualiza diariamente y permite al usuario:
- Localizar las estaciones más económicas por municipio, provincia y comarca.
- Consultar su evolución histórica
- Encontrar dónde repostar más barato cerca del usuario.
Punto Muerto reúne los datos necesarios para saber lo que cuesta tener coche en España, todos procedentes de fuentes oficiales y citando siempre en cada apartado la fuente oficial y sus condiciones de reutilización, salvo cuando un dato no está disponible, que se indica expresamente.
Reutiliza los precios del Geoportal de Carburantes del Ministerio para la Transición Ecológica y el Reto Demográfico (MITECO), actualizados cada 30 minutos, para mostrar diversos datos y utilidades sobre el coste actual de la gasolina, el diésel, el GLP:
- Precio medio nacional de los combustibles y su evolución diaria.
- Precios por comunidad autónoma, por provincia y por municipio.
- Mapa de las más de 11.000 estaciones del país.
- Buscador de las gasolineras más baratas próximas a una ubicación concreta.
Incluye además herramientas de cálculo sobre normativa y datos públicos:
- Calendario de la ITV según el RD 920/2017.
- Etiqueta ambiental de la DGT y zonas de bajas emisiones por ciudad.
- Cálculo del impuesto de circulación (IVTM).
- Cálculo del coste de la transferencia de un vehículo.
- Valor fiscal del vehículo según las tablas publicadas en el BOE.
- Cálculo del año de matriculación a partir de la matrícula.
- Equivalencias de medidas de neumático conforme al Manual de Reformas de Vehículos.
Es de uso gratuito y no requiere registro.
LitroReal es un ecosistema digital para la consulta y optimización del gasto en combustible en España, que reutiliza los datos abiertos del Geoportal de Gasolineras del Ministerio para la Transición Ecológica y el Reto Demográfico (MITECO).
Sus principales características son:
- Búsqueda por municipio: listados actualizados y optimizados de todas las estaciones de servicio de España organizados por localidad.
- Planificador de rutas inteligente: permite trazar trayectos con múltiples paradas (waypoints), filtrando por desvío máximo en kilómetros y tipo de combustible para encontrar el mayor ahorro real durante el viaje.
- Histórico de precios: gráfico de evolución del precio de cada gasolinera por tipo de combustible, con rango de fechas configurable.
- Gestión de favoritos: sección personalizada para acceder instantáneamente a las estaciones de servicio habituales del usuario.
- Tecnología PWA: aplicación web accesible desde cualquier dispositivo móvil, sin necesidad de descargas desde tiendas, ofreciendo fluidez nativa y geolocalización precisa.
- Privacidad y seguridad: cumplimiento estricto del Reglamento General de Protección de Datos, con herramientas integradas para el ejercicio de derechos ARSOL (acceso, rectificación, supresión, oposición y limitación del tratamiento) y descarga de datos personales.
El registro de usuarios en la aplicación es opcional y gratuito, facilitando la posibilidad de configurar sus propios descuentos de fidelización en diferentes compañías, que son aplicados en tiempo real al precio final neto mostrado directamente en los listados.
La aplicación apuesta por la transparencia y la utilidad ciudadana, ofreciendo el máximo rendimiento y rapidez tanto en escritorio como en dispositivo móvil.
Introducción
En los últimos años hemos visto cómo la inteligencia artificial generativa ha dejado de ser una curiosidad técnica para convertirse en una herramienta cotidiana en el flujo de trabajo de los profesionales del dato. Sin embargo, sigue existiendo una pregunta importante: ¿cómo se traduce esta tecnología en un proceso real de análisis de datos abiertos?, ¿Qué cambia en la práctica cuando un analista trabaja "junto a" un modelo de lenguaje en lugar de hacerlo en solitario?
Este post documenta un ejercicio práctico realizado con datos publicados en el portal datos.gob.es: el análisis de precios de las más de 11.000 estaciones de servicio en España. A diferencia de otros ejercicios publicados en este espacio, el análisis no se ha realizado de forma manual línea por línea, sino que se ha llevado a cabo en un entorno agéntico: una interfaz conversacional apoyada en un modelo grande de lenguaje (LLM) y un sistema de codificación asistido por inteligencia artificial. En la práctica, esto significa que en lugar de escribir el código de análisis nosotros mismos, le describimos al sistema en lenguaje natural qué queremos obtener, y este lo implementa.
El objetivo de este post es doble. Por un lado, explicar el análisis propiamente dicho: qué preguntas nos hacemos sobre los datos, qué problemas técnicos encontramos y qué conclusiones extraemos. Por otro, reflexionar sobre el método: cómo se estructura un proceso de análisis cuando trabajamos con un copiloto de IA, qué patrones de interacción funcionan mejor y dónde están los límites de la asistencia automatizada.
Nota metodológica: para la realización de este ejercicio hemos empleado una metodología Spec Driven Development (SDD), que guía a la IA a través de un proceso estructurado con el objetivo de evitar que la conversación pierda el foco del ejercicio. La explicación detallada de esta metodología queda fuera del alcance del presente post, pero el lector encontrará en el repositorio especificaciones, planes técnicos y checklists que la documentan.
Accede al repositorio del laboratorio de datos en GitHub
Accede al notebook de Google Colab
En este vídeo, el autor te explica que vas a encontrar tanto en el GitHub como en Google Colab.
El proceso: un flujo clásico, asistido por IA
Antes de entrar en cada fase, conviene describir el esquema general del trabajo. El análisis sigue cinco etapas habituales en ciencia de datos —ingesta, limpieza, exploración, ingeniería de variables y análisis de impacto— pero introduciendo en cada una de ellas un patrón conversacional con la IA.
Ese patrón puede resumirse en cinco pasos:
- Describir el problema en lenguaje natural.
- Proponer una primera solución (lo hace la IA).
- Cuestionar los supuestos de esa propuesta (lo hace el analista humano).
- Refinar la solución hasta que sea robusta.
- Documentar el patrón para reutilizarlo en futuros proyectos.
A continuación, veremos, fase por fase, cómo se materializa este patrón en el análisis del precio de los combustibles. Cada apartado comienza explicando el reto conceptual, continúa describiendo cómo abordamos la resolución con la asistencia de la IA, y termina mostrando el código resultante y las lecciones aprendidas.
Fase 1: ingesta robusta de datos desde una API pública
El reto: API públicas que no siempre responden como se espera
Aviso para el lector: esta fase entra en cierto detalle técnico sobre integración de API, errores SSL y estrategias de respaldo. Si tu perfil es más analítico que de desarrollo, puedes hojear el bloque de código y centrarte en los apartados El enfoque y Reflexión, donde la idea de fondo —cómo diseñar una ingesta tolerante a fallos— se explica sin entrar en detalles de implementación.
La descarga de datos desde la API del Ministerio para la Transición Ecológica es conceptualmente sencilla: una petición HTTP GET a un endpoint conocido debería devolver un fichero JSON con aproximadamente 11.000 estaciones de servicio. En la práctica, sin embargo, las API públicas presentan dificultades habituales que cualquier analista termina encontrando antes o después:
- Certificados SSL caducados o mal configurados, que provocan errores del tipo SSLError.
- Bloqueo de IP procedentes de servidores en la nube (Google Colab, AWS, etc.), interpretadas como tráfico sospechoso.
- Servidores inestables, con tiempos de respuesta variables y timeouts esporádicos.
- Inconsistencias en la documentación, por ejemplo, cuando se describe una respuesta JSON pero el servidor devuelve XML.
La pregunta clave es: ¿cómo diseñamos un sistema de ingesta que tolere estos problemas en lugar de fallar al primer obstáculo?
El enfoque: una arquitectura de respaldos escalonados
En ingeniería de software, los sistemas críticos no dependen de un único componente. Cuando un canal falla, existe otro de respaldo (lo que en inglés se denomina fallback). Aplicar esta lógica a la ingesta de datos es especialmente útil cuando trabajamos con fuentes públicas sobre las que no tenemos control.
Para este ejercicio, diseñamos una estrategia de triple respaldo:
- Primer intento — requests con configuración permisiva: realizamos la petición HTTP con la librería estándar de Python, pero configurando un User-Agent que simula un navegador real y desactivando la verificación de SSL. Esto resuelve buena parte de los problemas de certificados.
- Segundo intento — curl desde la shell: si requests falla, invocamos curl como subproceso. La razón es que curl utiliza una pila TLS distinta a la de Python y no envía los mismos certificados, lo que permite sortear ciertos tipos de bloqueo.
- Tercer intento — datos de demostración: si todo lo anterior falla, generamos un conjunto sintético de 11.000 estaciones de servicio con distribuciones realistas. Esto garantiza que el notebook siempre sea ejecutable en un contexto educativo, aunque la API esté caída.
El razonamiento de fondo es sencillo: cada método sortea un tipo distinto de fallo de red, y su combinación proporciona robustez. A continuación, mostramos el código que implementa esta arquitectura.
El código resultante
El siguiente fragmento ilustra cómo se materializan los tres niveles de respaldo en una única función. Las cláusulas try/except permiten detectar el fallo de cada método y pasar automáticamente al siguiente:
def descargar_datos_api(url):
"""
Descarga datos con triple respaldo:
1. requests con verify=False (sortea problemas de SSL)
2. curl -k (pila TLS alternativa)
3. datos sintéticos (garantía de ejecución)
"""
# Intento 1: requests con cabeceras de navegador
try:
sesion = requests.Session()
sesion.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
})
response = sesion.get(url, timeout=45, verify=False)
return response.json()
except Exception as e_requests:
print(f"[Respaldo 1] requests ha fallado: {e_requests}")
# Intento 2: curl como subproceso
try:
resultado = subprocess.run(
["curl", "-s", "-k", url],
capture_output=True, timeout=45, text=True
)
return json.loads(resultado.stdout)
except Exception as e_curl:
print(f"[Respaldo 2] curl ha fallado: {e_curl}")
# Intento 3: datos sintéticos de demostración
print("[Respaldo 3] Utilizando datos de demostración")
return generar_datos_demo_gasolineras(11000)
Reflexión: dónde aporta valor la IA en esta fase
La iteración con la IA no produjo el código anterior de un solo intento. El proceso real fue más interesante: planteamos el problema ("la API a veces rechaza las peticiones, necesito respaldos"), la IA propuso una solución inicial, y el avance vino de cuestionar esa propuesta. La pregunta "¿por qué curl debería funcionar si requests ya ha fallado?" obligó al modelo a explicar las diferencias entre ambas pilas TLS, lo que a su vez nos permitió validar que la solución tenía fundamento técnico real, no era simplemente "probar lo mismo dos veces".
Una estimación razonable: resolver este problema mediante prueba y error puro habría llevado entre dos y tres horas de depuración. Con la iteración asistida, lo abordamos en aproximadamente treinta minutos.
Fase 2: limpieza con conocimiento de dominio
El reto: los datos reales nunca son perfectos
Una vez descargados los datos, comienza el trabajo menos visible pero más decisivo de cualquier análisis: la limpieza y preparación. La calidad del resultado final depende en gran medida del cuidado puesto en esta etapa. En el caso de los combustibles, las inconsistencias más habituales son:
- Variantes textuales no normalizadas: la marca "MOEVE" puede aparecer como "MOEVE", "Moeve" o "moeve" en distintos registros. Para una persona son obviamente la misma marca, pero en una agregación por groupby aparecen como tres categorías independientes.
- Coordenadas geográficas incorrectas: puntos situados fuera del territorio español (islas remotas, fragmentos de Marruecos, errores de captura).
- Separadores decimales inconsistentes: precios codificados como "1,349" con coma, que requieren conversión explícita antes de poder operar con ellos.
- Conversiones que introducen valores nulos: pd.to_numeric(..., errors='coerce') es muy útil, pero genera NaN silenciosos que pueden romper análisis posteriores.
La cuestión central de esta fase es: ¿cómo traducimos el conocimiento humano sobre el dominio en reglas de código?
El enfoque: validación organizada en capas
En lugar de limpiar "según va apareciendo", conviene organizar las reglas de validación en capas, cada una con una responsabilidad clara:
|
Capa |
Responsabilidad |
Ejemplo |
|---|---|---|
| Tipos | Conversión y coerción a tipos adecuados | Precio como float, fecha como datetime |
| Rangos | Valores dentro de límites razonables | Precio entre 0,5€ y 3,0€ por litro |
| Semántica | Coherencia con el dominio | Coordenadas dentro de España, marcas normalizadas |
Figura 1. Tabla de validación organizada en capas. Fuente: elaboración propia - datos.gob.es
La pregunta que cada capa debe responder es siempre la misma: ¿tiene sentido este valor en el contexto de las estaciones de servicio españolas? La novedad respecto a un flujo manual es que aquí describimos las reglas a la IA en lenguaje natural y dejamos que ella las traduzca a código pandas. Nosotros conservamos la responsabilidad de definir qué es válido y qué no.
El código resultante
El siguiente bloque implementa las tres capas de validación de forma secuencial. Conviene destacar que la lista de aliases de marcas (CEPSA → MOEVE) refleja conocimiento de negocio específico —el rebranding de CEPSA a MOEVE en 2023— que la IA no podría inferir por sí sola; es información que aporta el analista. Este es un ejemplo muy claro de aportación del conocimiento humano difícilmente alcanzable por la IA:
def validar_y_limpiar_carburantes(df):
# Capa 1: normalización de tipos
df['precio'] = (
df['precio'].astype(str)
.str.replace(',', '.')
.astype(float)
)
df['marca'] = df['marca'].str.upper().str.strip()
# Capa 2: validación de rangos
df = df[(df['precio'] >= 0.5) & (df['precio'] <= 3.0)]
df = df[
(df['latitud'] >= 27.5) & (df['latitud'] <= 43.8) &
(df['longitud'] >= -18.2) & (df['longitud'] <= 4.4)
]
# Capa 3: coherencia semántica (conocimiento de negocio)
aliases = {'CEPSA': 'MOEVE'} # Rebranding 2023
df['marca'] = df['marca'].map(lambda x: aliases.get(x, x))
# Auditoría de nulos
nulos = df[['precio', 'latitud', 'longitud', 'marca']].isnull().sum()
if nulos.sum() > 0:
print(f"Atención: se han detectado valores nulos:\n{nulos}")
return df.dropna(subset=['precio', 'latitud', 'longitud'])Reflexión: el reparto del trabajo entre la IA y el analista
Esta fase es especialmente reveladora del tipo de colaboración que la IA habilita. Las reglas más técnicas (conversión de tipos, detección de nulos, normalización de mayúsculas) son prácticamente automáticas: basta con describir el problema y el modelo propone una implementación correcta. En cambio, las reglas que dependen del dominio (que las islas Canarias tienen un sobrecoste logístico del 5%, que CEPSA y MOEVE son la misma marca tras la fusión, que un precio inferior a 0,5€ es probablemente un error de carga) deben ser especificadas por el analista humano.
La lección aprendida es importante: la calidad de la limpieza depende directamente del conocimiento de dominio que aporta el analista. La IA acelera la implementación, pero no inventa contexto. Por eso el patrón reutilizable es el mismo en cualquier proyecto: describe tu dominio con detalle, deja que la IA escriba las validaciones, y verifica tú mismo que los resultados son coherentes.
Fase 3: análisis exploratorio visual (EDA)
El reto: convertir números en intuiciones
Con 11.000 registros limpios ya en memoria, el siguiente paso es responder a las preguntas de negocio que motivaron el análisis. En este caso, formulamos cuatro preguntas concretas:
- ¿Qué provincias tienen los combustibles más caros?
- ¿Existe relación entre la ubicación geográfica (latitud y longitud) y el precio?
- ¿Hay diferencias significativas entre marcas?
- ¿Cómo se distribuyen los precios (media, mediana, valores atípicos)?
El reto técnico no es complejo —pandas y matplotlib resuelven cualquiera de estas preguntas— pero sí lo es el reto metodológico: elegir la visualización adecuada para cada pregunta. Una gráfica mal elegida puede ocultar tanto como una agregación incorrecta.
El enfoque: cada pregunta determina su gráfico
En análisis exploratorio existe una correspondencia natural entre el tipo de pregunta y la visualización más apropiada. Conviene tenerla presente antes de escribir una sola línea de código:
|
Pregunta |
Visualización adecuada |
Razón |
|---|---|---|
| ¿Ranking? | Gráfico de barras ordenado | Permite comparar valores ordenados |
| ¿Relación espacial? | Scatter con escala de color | Muestra correlación en dos dimensiones |
| ¿Distribución y atípicos? | Diagrama de caja (box plot) | Revela mediana, cuartiles y outliers |
| ¿Diferencias entre grupos? | Box plot o violin plot | Compara distribuciones simultáneamente |
Figura 2. Tabla de correspondencia natural entre el tipo de pregunta y la visualización más adecuada. Fuente: elaboración propia - datos.gob.es
El objetivo no es producir gráficos vistosos, sino gráficos que respondan a preguntas concretas. Esta es una idea aparentemente obvia, pero conviene recordarla: en la práctica, es frecuente que se generen visualizaciones por inercia, sin tener claro qué se quiere mostrar.
El código resultante
A continuación, mostramos uno de los gráficos como ejemplo, el ranking de precios por provincia. La estructura es siempre la misma: declaración del gráfico, configuración estética, y un breve comentario interpretando el resultado:
# Pregunta 1: ¿qué provincias son las más caras?
top_provincias = (
df.groupby('provincia')['precio']
.mean()
.sort_values(ascending=False)
.head(12)
)
fig, ax = plt.subplots(figsize=(12, 6))
top_provincias.plot(kind='bar', ax=ax, color='steelblue')
ax.set_title('Precio medio del combustible por provincia (Top 12)',
fontsize=14, fontweight='bold')
ax.set_ylabel('Precio (€/litro)')
ax.set_xlabel('Provincia')
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.show()
# Hallazgo: las tres provincias más caras son insulares o costeras
# (Baleares, Canarias, Tarragona). Hipótesis: el coste logístico
# y la lejanía a los hubs de distribución elevan el precio.En el caso del scatter geográfico, aplicamos una segmentación adicional —península, Baleares y Canarias— para visualizar simultáneamente la ubicación y la insularidad. Esta segmentación reveló un patrón que ninguna agregación numérica había mostrado claramente: las estaciones insulares tienen precios sistemáticamente superiores, hallazgo probablemente atribuible a costes de transporte marítimo. El insight no emergió de un cálculo, sino de la visualización.
Reflexión: el punto ciego de la IA
Esta fase pone de manifiesto una limitación importante del modelo: la IA no ve el resultado gráfico. Puede sugerir el tipo de visualización adecuado, escribir el código correctamente y proponer una paleta de colores, pero no puede juzgar si la escala del eje es apropiada, si la densidad de puntos satura el gráfico o si los rótulos se solapan. Todas estas validaciones siguen siendo responsabilidad humana.
En la práctica, esto significa que la fase de EDA es la que requiere más iteración entre persona y máquina: la IA escribe, el analista observa, identifica un problema visual ("este eje no muestra bien la variación"), y describe la corrección ("ajusta el eje Y a [precio_min0.95, precio_max1.05]"). El patrón reutilizable es claro: una pregunta clara, un tipo de gráfico adecuado y una validación visual humana.
Fase 4: ingeniería de variables (feature engineering)
El reto: capturar variación con nuevas variables
El análisis exploratorio identifica patrones, pero rara vez los explica. Para entender qué factores influyen en el precio es necesario construir nuevas variables —features— que capturen hipótesis específicas sobre la dinámica del mercado. En este ejercicio formulamos tres hipótesis:
- Temporal: ¿Influye el día de la semana en el precio? ¿Es más caro repostar en fin de semana?
- Geográfica: ¿Influye la distancia a un hub económico (en este caso, Madrid)?
- Regional: ¿Existen diferencias estructurales entre el norte, el centro y el sur de España?
La ingeniería de variables consiste precisamente en traducir esas hipótesis en columnas calculadas que el resto del análisis pueda utilizar.
El enfoque: cada variable, una historia testable
Una buena variable debe contar una historia clara. No basta con calcular un número: hay que poder explicar qué pregunta intenta responder. En nuestro caso:
- es_fin_semana (0/1): ¿cambia el precio el sábado y el domingo?
- distancia_a_madrid (km): ¿se encarece el combustible al alejarse del hub logístico?
- region (norte/centro/sur): ¿hay brechas estructurales entre regiones?
Cada una de estas tres variables es, en realidad, una pregunta empírica disfrazada de columna. Si la variable no explica nada cuando la cruzamos con el precio, simplemente la descartamos.
El código resultante
Implementamos las tres variables en una única función. La más interesante técnicamente es la distancia a Madrid, que requiere la fórmula de Haversine para calcular distancias sobre la superficie terrestre teniendo en cuenta la curvatura del planeta:
from math import radians, cos, sin, asin, sqrt
def crear_features_carburantes(df):
# Variable temporal
df['es_fin_semana'] = (
df['fecha'].dt.dayofweek.isin([5, 6]).astype(int)
)
# Variable geográfica: distancia haversine a Madrid
madrid_lat, madrid_lon = 40.4168, -3.7038
def haversine(lat, lon):
lat, lon = radians(lat), radians(lon)
m_lat, m_lon = radians(madrid_lat), radians(madrid_lon)
dlat = lat - m_lat
dlon = lon - m_lon
a = sin(dlat/2)**2 + cos(m_lat) * cos(lat) * sin(dlon/2)**2
return 6371 * 2 * asin(sqrt(a)) # radio de la Tierra en km
df['distancia_a_madrid'] = df.apply(
lambda r: haversine(r['latitud'], r['longitud']), axis=1
)
# Variable regional
def region(lat):
if lat >= 42: return 'Norte'
if lat >= 39: return 'Centro'
return 'Sur'
df['region'] = df['latitud'].apply(region)
return dfReflexión: proponer variables con argumento, no solo con código
En esta fase la IA aporta un valor especialmente alto, pero no en lo que se podría pensar a primera vista. Lo verdaderamente útil no es que escriba la fórmula de Haversine —cualquier referencia técnica la contiene—, sino que proponga variables candidatas con argumentación detrás. Cuando le preguntamos "¿qué features podrían capturar la variación de precios?", la propuesta vino acompañada de razonamiento: Madrid se sugirió como hub porque es el mercado más eficiente y estable, y por tanto las desviaciones respecto a su precio funcionan como aproximación a la fricción logística.
Ese razonamiento es lo valioso: no la fórmula, sino la justificación. Trial-and-error puro habría llevado tres o cuatro horas explorando variables hasta encontrar las útiles; con la iteración asistida, llegamos a un conjunto razonado en aproximadamente cuarenta y cinco minutos.
Fase 5: análisis de impacto de las variables
El reto: cuantificar la contribución real
Construir variables es una cosa; demostrar que realmente explican algo es otra. En esta última fase del análisis evaluamos el impacto efectivo de cada una de las tres variables creadas, combinando dos enfoques: una medida numérica (correlación o diferencia de medias) y una representación visual que permita interpretar el resultado de un vistazo.
El enfoque: dos enfoques complementarios
Para cada variable, calculamos:
- Una medida numérica que cuantifica el efecto (correlación de Pearson para variables continuas; diferencia de medias para categóricas).
- Una representación visual que permite interpretar la magnitud del efecto y detectar relaciones no lineales.
El cruce de ambos enfoques es lo que da fiabilidad al resultado. Una correlación alta sin una visualización que la respalde puede ser engañosa (por ejemplo, si está dominada por outliers); una visualización sugestiva sin métrica puede llevar a sobreinterpretación.
El código resultante
Como ejemplo, mostramos el análisis de impacto de la distancia a Madrid. Primero calculamos la correlación, después segmentamos en cuartiles para hacer la relación visualmente interpretable:
# Medida numérica
correlacion = df['distancia_a_madrid'].corr(df['precio'])
print(f"Correlación (distancia a Madrid → precio): {correlacion:.3f}")
# Representación visual por cuartiles de distancia
df['cuartil_distancia'] = pd.qcut(
df['distancia_a_madrid'], q=4,
labels=['Q1 (cercano)', 'Q2', 'Q3', 'Q4 (lejano)']
)
precio_por_cuartil = df.groupby('cuartil_distancia')['precio'].mean()
fig, ax = plt.subplots(figsize=(10, 5))
precio_por_cuartil.plot(kind='bar', ax=ax, color='#2ecc71')
ax.set_title('Impacto geográfico: precio medio por cuartiles de distancia a Madrid')
ax.set_ylabel('Precio medio (€/litro)')
plt.xticks(rotation=0)
plt.tight_layout()
plt.show()El patrón emergente del análisis completo —comparando las tres variables— es que la distancia a Madrid es la más explicativa, seguida por la región, y por último por el efecto fin de semana, que en nuestro periodo de estudio resulta ser marginal. En conjunto, las tres variables explican aproximadamente el 60-70% de la variación de precios; el resto depende de factores como la marca específica, el tipo de estación (autopista, urbana, rural) y eventos puntuales del mercado.
Reflexión: no todas las variables impactan por igual
Una de las virtudes de este análisis estructurado es que revela cuáles de nuestras hipótesis iniciales se sostienen y cuáles no. En este caso, la hipótesis temporal (fin de semana) resultó ser mucho más débil de lo esperado, mientras que la hipótesis geográfica se confirmó con claridad. Sin este paso de cuantificación, habríamos podido seguir asumiendo que todas las variables aportan información valiosa.
Síntesis: las lecciones técnicas que nos llevamos
A lo largo de las cinco fases anteriores hemos ido acumulando soluciones a problemas concretos. La siguiente tabla resume las más reutilizables; cada una está documentada con mayor detalle en el directorio prompts del repositorio:
|
Fase |
Problema |
Solución |
Reutilizable en |
|---|---|---|---|
| Ingesta | Bloqueos SSL o de IP en APIs | Triple respaldo: request -> curl -> demo | Cualquier API pública |
| Ingesta | Documentación inconsistente | Validación de estructura + manejo de errores | APIs gubernamentales |
| Limpieza | Variantes textuales en marcas | .st.upper().str.trip() antes de agrupar | Cualquier agregación categórica |
| Limpieza | Coordenadas fuera de España | Bounding box [27.5-43.8, -18.2- 4.4] | Análisis geográficos en España |
| Limpieza | Rangos comprimidos en gráficos | ax.set_xlim(min*0.95, max*1.05) | Visualización con rangos estrechos |
| EDA | Elección de tipo de gráfico | Mapeo explícito pregunta -> gráfico | Cualquier EDA |
| Features | Variables sin justificación | Cada feature responde una hipótesis testable | Feature engineering en general |
| Análisis | Impacto no cuantificado | Métrica + visualización en paralelo | Cualquier análisis de impacto |
Figura 3. Tabla resumen de soluciones a problemas concretos. Fuente: elaboración propia - datos.gob.es
Reflexión final: qué hace que la IA sea un buen copiloto
Al cabo del ejercicio, podemos extraer algunas conclusiones generales sobre el uso de IA generativa como apoyo al análisis de datos. Las dividimos en dos planos: dónde aporta valor, y dónde no debe sustituir al criterio humano.
Donde la IA aporta valor de forma clara:
- Iteración rápida. El ciclo "describir problema – obtener solución – validar" se reduce de horas a minutos. Esto cambia cualitativamente la dinámica de trabajo: nos permite probar ideas que de otro modo descartaríamos por coste.
- Pensamiento lateral. La IA propone alternativas que un analista podría pasar por alto, como la idea de usar curl cuando requests falla. No siempre acierta, pero sí amplía el espacio de soluciones consideradas.
- Documentación articulada. La IA es especialmente buena explicando el porqué de una decisión técnica, no solo el qué. Esto facilita que el código resultante sea legible para personas no técnicas.
Donde el criterio humano sigue siendo imprescindible:
- Conocimiento de dominio. La IA no sabe que CEPSA y MOEVE son la misma marca, ni que Canarias tiene un sobrecoste logístico estructural. Esa información debe aportarla el analista.
- Validación estadística. La IA puede sugerir modelos, pero la validez estadística del análisis es responsabilidad humana.
- Lectura de gráficos. La IA no ve sus propias visualizaciones. El juicio sobre si una gráfica es legible, comunica lo que se pretende y respeta buenas prácticas visuales sigue siendo humano.
- Decisiones de negocio. Qué preguntar a los datos, qué considerar relevante, cómo comunicar los resultados a la organización: son decisiones que la IA puede apoyar, pero no sustituir.
En síntesis, la idea que resume mejor nuestra experiencia es la siguiente: la IA generativa funciona mejor cuando piensa con nosotros que cuando piensa por nosotros. El ejercicio que aquí presentamos no fue "pedir a Claude que hiciera el análisis", sino mantener una conversación estructurada en la que la IA proponía, el analista cuestionaba, la IA refinaba y el analista validaba. El resultado de esa conversación es un análisis más robusto, mejor documentado y más reutilizable que el que habríamos producido en solitario.
Cómo aprovechar este repositorio
El código completo, los prompts y la documentación están disponibles en el repositorio público del proyecto. Distintos perfiles pueden aprovecharlo de formas distintas:
- Si estudias análisis de datos: abre directamente el notebook en Google Colab y recorre cada celda en orden. Para cada visualización, consulta el prompt correspondiente en prompts/visualizacion/.
- Si trabajas como científico de datos: revisa specs/001-carburantes-ia/plan.md, donde están documentadas las decisiones arquitectónicas y las lecciones aprendidas. Los snippets de prompts/ son reutilizables tal cual en otros proyectos.
- Si te interesa la metodología de prompt engineering: el patrón "describe – cuestiona – refina – valida" está documentado caso por caso a lo largo de los prompts. Es replicable en cualquier dominio: finanzas, salud, marketing o cualquier análisis de datos abiertos.
Conclusión
El ejercicio que hemos presentado muestra que la IA generativa, utilizada con criterio, puede acelerar de manera notable el análisis de datos abiertos sin sacrificar rigor metodológico. Las cinco fases recorridas —ingesta, limpieza, exploración, ingeniería de variables y análisis de impacto— siguen siendo las mismas que en un flujo tradicional, pero la dinámica de trabajo cambia: pasamos de escribir código a describir intenciones y validar resultados.
Contenido elaborado por Alejandro Alija, experto en Transformación Digital e Innovación. Los contenidos y los puntos de vista reflejados en esta publicación son responsabilidad exclusiva de su autor
Esta aplicación está focalizada en la búsqueda de gasolineras baratas (low cost). El objetivo es que los usuarios puedan elegir y pagar lo menos posible por cada repostaje, encontrando la gasolinera más barata cerca de su posición o en su ruta. Incluye gasolineras de España, Francia, Portugal e Italia.
El usuario puede navegar por el mapa interactivo o introducir un municipio en el buscador y la aplicación le indicará que gasolineras están cerca de su ubicación y cuál es el precio de los distintos tipos de carburantes en tiempo real. También pueden indicar la ruta a realizar para que les muestre las mejores opciones de repostaje durante el trayecto.
La aplicación también informa sobre el precio medio de los distintos carburantes, así como su evolución en el último año. Incluye datos por país, marca, comunidad autónoma o provincia.
Fuelconomy es una plataforma gratuita de comparación de precios de combustible, que abarca más de 52.000 gasolineras en Francia, España, Italia, Reino Unido y Portugal. Recopila datos oficiales de precios proporcionados por los gobiernos (incluido datos.gob.es para España) en una única base de datos en tiempo real, que se actualiza dos veces al día.
Los usuarios pueden comparar los precios del combustible en un mapa interactivo, encontrar la gasolinera más barata cercana, consultar el historial de precios de los últimos 30 días, configurar alertas de precios y planificar rutas eficientes en cuanto al consumo de combustible.
La aplicación está disponible en 5 idiomas (inglés, francés, español, italiano y portugués).