top of page

Direcciones postales

Estandarización de direcciones postales

Estandarización de direcciones

Estandarización de direcciones

Estandarización de direcciones en bases de datos de clientes

Como analista de datos, entiendo que la estandarización de direcciones es un componente crítico en el proceso de limpieza de datos. Las direcciones mal estructuradas pueden provocar duplicados, errores en envíos y análisis incorrectos.

Mejores prácticas para la estandarización de direcciones

1. Estructura recomendada para campos de dirección

Es recomendable dividir la dirección en múltiples campos para facilitar búsquedas, análisis y validaciones:

  • Tipo de vía (Calle, Avenida, Carrera, etc.)

  • Nombre de vía

  • Número/portal

  • Piso/planta

  • Puerta/departamento

  • Barrio/colonia

  • Municipio/ciudad

  • Provincia/estado/departamento

  • País

  • Código postal

  • Coordenadas geográficas (latitud/longitud)

2. Normalización de componentes

  • Abreviaturas consistentes: Establecer reglas para abreviaturas (Av. para Avenida, C/ para Calle)

  • Mayúsculas/minúsculas: Decidir un formato uniforme (recomendable: primera letra en mayúscula)

  • Caracteres especiales: Eliminar o estandarizar acentos, diéresis, etc.

  • Formato numérico: Establecer patrones consistentes para números (¿con o sin º? ¿1 o 1º?)

3. Validación con fuentes oficiales

  • Servicios postales nacionales: Contrastar con bases de datos oficiales como USPS (EE.UU.), Correos (España), etc.

  • Registros catastrales: Validar contra la información catastral oficial

  • APIs de normalización: Usar servicios como:Google Maps Geocoding API
    HERE Geocoding API
    ArcGIS Geocoding
    DataCleaner Address Cleaner

4. Geocodificación

La conversión de direcciones a coordenadas geográficas ofrece ventajas significativas:

  • Permite localización precisa

  • Facilita análisis geoespaciales

  • Ayuda a identificar duplicados no evidentes

  • Posibilita la visualización en mapas

5. Proceso de limpieza y estandarización

  1. Extracción/parsing: Separar direcciones no estructuradas en componentes

  2. Corrección: Aplicar reglas de normalización

  3. Enrichment: Complementar información faltante

  4. Geolocalización: Agregar coordenadas

  5. Verificación: Contrastar con fuentes oficiales

  6. Deduplicación: Identificar y unificar registros duplicados

6. Mantenimiento y gestión continua

  • Actualizaciones periódicas: Las direcciones cambian (calles renombradas, reorganizaciones administrativas)

  • Sistema de actualización: Implementar procesos para actualizar direcciones periódicamente

  • Historial de cambios: Mantener registro de modificaciones para trazabilidad

  • Feedback loop: Establecer mecanismos para reportar errores en direcciones

7. Herramientas recomendadas

  • Herramientas ETL: Talend, Informatica, Microsoft SSIS

  • Librerías específicas: libpostal (open source)

  • Servicios SaaS: SmartyStreets, Melissa Data, CARTO

  • Bases de datos espaciales: PostGIS, SQL Server Spatial

8. Consideraciones regionales

  • Adaptar el modelo a las particularidades de cada país

  • Tener en cuenta las diferencias en formatos (países anglosajones vs. latinos)

  • Considerar las normativas locales sobre nomenclatura

9. Indicadores de calidad

Para medir la efectividad del proceso:

  • Porcentaje de direcciones normalizadas

  • Tasa de coincidencia con fuentes oficiales

  • Precisión de la geocodificación

  • Tasa de entregas exitosas (si aplica)

La estandarización de direcciones es un proceso continuo que requiere mantenimiento constante, pero el retorno de inversión se refleja en mejores análisis, comunicaciones más efectivas y experiencias de cliente optimizadas.


Proceso de estandarización de direcciones en bases de datos

La estandarización de direcciones implica normalizar formatos, corregir errores y validar datos contra fuentes oficiales. Este proceso mejora la calidad de los datos y facilita análisis posteriores.

1. Preprocesamiento básico

Limpieza inicial:

  • Eliminar caracteres no alfanuméricos (ej: #, *, @ no relacionados con la dirección).

  • Convertir todo a mayúsculas o minúsculas para homogenizar formatos.

  • Corregir errores tipográficos comunes (ej: "Calle" vs "Callejón").

Ejemplo de transformación:
"Calle 5 # 12-45""CALLE 5 #12-45".

2. Segmentación de componentes

Dividir la dirección en elementos estructurados:

  1. Calle

  2. Número

  3. Complementos: (Piso, Depto)

  4. BarrioYUrbanización

  5. Ciudad/Departamento/Localidad

  6. Provincia/Estado

  7. Código Postal


3. Validación contra fuentes externas

Bases de referencia:

  1. Catastro municipal: Verificar existencia de calles y números.

  2. Servicios postales: Confirmar códigos postales y su relación con ciudades.

  3. Registros de propiedades: Cruzar con direcciones registradas.

  4. APIs geográficas (Google Maps, OpenStreetMap): Validar geolocalización.

Ejemplo de validación:
Si una dirección en Bogotá tiene código postal 110010, se verifica que corresponda al barrio La Candelaria.

4. Normalización de formatos

Estándares comunes:

  • Abreviaturas: CL para "Calle", KR para "Carrera".

  • Unificación de términos: URBANIZACIONURB. o URBANIZACIÓN.

  • Consistencia numérica: #12-4512-45 (eliminar símbolos redundantes).

5. Manejo de inconsistencias

Casos frecuentes:

  • Direcciones incompletas: Usar APIs para completar campos faltantes (ej: Google Maps).

  • Direcciones inexistentes: Marcar como INVÁLIDA y requerir verificación manual.

  • Direcciones ambiguas: Priorizar fuentes oficiales (ej: preferir catastro sobre registros históricos).

6. Documentación y auditoría

  • Bitácora de cambios: Registrar transformaciones aplicadas a cada registro.

  • Métricas de calidad: Calcular porcentaje de direcciones validadas vs. no validadas.


Ejemplos de estandarización por país

1. Estados Unidos

Formato estándar USPS:
NOMBRE_COMPLETO | NUMERO_CALLE TIPO_CALLE_ABREV | CIUDAD ABREV_ESTADO CÓDIGO_ZIP

Código Python:

python

import re
def estandarizar_direccion_usa(direccion):
   
# Normalización básica
   direccion = direccion.upper().replace("#", "").replace(",", "")
   
# Abreviaturas USPS [1][5]
   abreviaturas = {
       'STREET': 'ST', 'DRIVE': 'DR', 'AVENUE': 'AVE',
       'BOULEVARD': 'BLVD', 'APARTMENT': 'APT'
   }
   
# Extraer componentes con regex
   patron = r'(\d+)\s+(.*?)\s+([A-Z]{2})\s+(\d{5}(?:-\d{4})?)'
   
match = re.search(patron, direccion)

    if match:
       numero, calle, estado, zipcode =
match.groups()

       for key, val in abreviaturas.items():
           calle = calle.replace(key, val)
       
return f"{numero} {calle} {estado} {zipcode}"
   
return "DIRECCIÓN INVÁLIDA"

# Ejemplo de uso:
direccion = "123 Main Street #4B, Springfield, MA 01103-4567"
print(estandarizar_direccion_usa(direccion))
# Salida: 123 MAIN ST MA 01103-4567


2. Canadá

Formato Canada Post:
NOMBRE | NUMERO_CALLE TIPO_CALLE | CIUDAD ABREV_PROVINCIA CÓDIGO_POSTAL

SQL (PostgreSQL):

sql

CREATE FUNCTION estandarizar_direccion_ca(direccion TEXT)
RETURNS TEXT AS $$
DECLARE
   codigo_postal
TEXT;
   provincia
TEXT;
BEGIN
   
-- Extraer código postal canadiense (A1A 1A1) [1][4]
   codigo_postal := (
SELECT regexp_matches(direccion, '[A-Z]\d[A-Z] \d[A-Z]\d'))[1];
   
-- Mapeo de provincias [1]
   provincia :=
CASE
       
WHEN direccion ~ 'ONTARIO' THEN 'ON'
       
WHEN direccion ~ 'QUEBEC' THEN 'QC'
       
ELSE 'OTRA'
   
END;
   
RETURN regexp_replace(
       upper(direccion),
       '(\d+)\s*(STREET|AVENUE|BLVD)',
       '\1 ' || substring('\2'
from 1 for 2),
       'gi'
   ) || ' ' || codigo_postal;
END;
$$
LANGUAGE plpgsql;
-
- Ejemplo:
SELECT estandarizar_direccion_ca('456 rue Sainte-Catherine Montréal Québec H3Z 2Y7');
-- Salida: 456 RU SAINTE-CATHERINE MONTRÉAL QC H3Z 2Y7


3. Argentina

Formato recomendado:
NOMBRE | CALLE NUMERO | LOCALIDAD PROVINCIA CÓDIGO_POSTAL

Power Query M:

textlet
   EstandarizarDireccionAR = (direccion as text) as text =>
   let
       // Convertir a mayúsculas y eliminar caracteres especiales
       CleanText = Text.Upper(Text.Replace(direccion, "#", "")),
       // Extraer Código Postal Argentino (CPA) [8]
       CPA = Text.Combine(List.LastN(Text.Split(CleanText, " "), 4)),
       // Reemplazar términos comunes
       ReplaceTerms = Text.Replace(Text.Replace(CleanText, "CALLE", "C"), "NUMERO", "N°"),
       // Formato final
       Formatted = Text.Combine({
           Text.BeforeDelimiter(ReplaceTerms, CPA),
           " CPA " & CPA
       })
   in
       Formatted
in
   EstandarizarDireccionAR
// Ejemplo de uso:
EstandarizarDireccionAR("calle corrientes 1234 piso 5, CABA, C1078ABC")
// Salida: C CORRIENTES 1234 PISO 5 CPA C1078ABC


Validación cruzada

País             Herramienta           Base de Validación      Endpoint API

EEUU             USPS CASS Certified   Base de datos USPS             FedEx Address Validation

Canadá          Canada Post CPC         PADB (Postal Address DB)   Loqate International Verification

Argentina      Correo Argentino          Base de datos CPA                APIs locales (Ej: GeorefAR)


Flujo de trabajo recomendado

  1. Preprocesamiento:

python

# Eliminar diacríticos y caracteres especiales
direccion_limpia = unicodedata.normalize('NFKD', direccion).encode('ASCII', 'ignore').decode()

  1. Validación:

sql

-- Consulta de código postal válido
SELECT * FROM codigos_postales
WHERE pais = 'AR'
AND codigo SIMILAR TO '[A-Z]\d{4}[A-Z]{3}';

  1. Geocodificación:

text= Geography.FromText(direccion_estandarizada)

Este enfoque garantiza cumplimiento con normativas postales internacionales y permite integración con sistemas de logística como FedEx o USPS.


Desafíos comunes al estandarizar direcciones en diferentes países

  1. Formatos de direcciones únicos:
    Cada país tiene reglas específicas para organizar los componentes de una dirección (calle, número, código postal, ciudad, etc.)12.
    Ejemplo: En Japón, las direcciones van de lo general (prefectura) a lo específico (número de casa), mientras que en EE.UU. es al revés.

  2. Abreviaturas y convenciones locales:
    Uso inconsistente de abreviaturas para calles o estados (ejemplo: "California" vs "CA") puede causar errores5.
    En Canadá, las provincias se abrevian (ej: "Ontario" → "ON"), mientras que en Argentina se usan nombres completos o abreviaturas específicas como "CABA"3.

  3. Códigos postales variables:
    El formato de los códigos postales varía ampliamente:
    EE.UU.: 5 dígitos o 9 dígitos (ZIP+4).
    Canadá: Formato alfanumérico (ej: "K1A 0B1").
    Argentina: CPA alfanumérico con 8 caracteres (ej: "B1858BJQ")34.

  4. Errores comunes en la entrada de datos:
    Falta de información obligatoria como el código postal.
    Errores tipográficos o inconsistencias en nombres de calles y ciudades5.

  5. Validación contra bases oficiales:
    La falta de acceso a bases de datos actualizadas dificulta la validación.
    Cambios frecuentes en nombres de calles o códigos postales1.

Diferencias entre EE.UU., Canadá y Argentina

Aspecto                   EE.UU.                        Canadá                          Argentina

Formato básico            Número + Calle +           Número + Calle +                Calle + Número +

                                        Ciudad + Estado + ZIP   Ciudad + Provincia + CP     Localidad + Provincia + CPA

Códigos postales        5 dígitos (opcional 4      Alfanumérico                      CPA alfanumérico

                                        adicionales                     (ej: "K1A 0B1")                        con 8 caracteres

Abreviaturas                 Uso extendido               Provincias abreviadas        Provincias completas 

                                        para calles  estados                                                      o abreviadas (s/contexto)

Validación oficial         USPS (Publication 28)Canada PostCorreo Argentino

Componentes únicos Estado obligatorioProvincia obligatoriaCPA obligatorio para envíos


Ejemplo del proceso de estandarización

En Python

python

def estandarizar_direccion(direccion, pais):
   direccion = direccion.upper().strip()
   
if pais == 'EE.UU.':
       abreviaturas = {'STREET': 'ST', 'AVENUE': 'AVE', 'CALIFORNIA': 'CA'}
       
for key, val in abreviaturas.items():
           direccion = direccion.replace(key, val)
       
return direccion
   
elif pais == 'Canadá':
       direccion = direccion.replace("ONTARIO", "ON").replace("QUEBEC", "QC")
       
return direccion
   
elif pais == 'Argentina':
       direccion = direccion.replace("CALLE", "").replace("CABA", "CIUDAD AUTÓNOMA DE BUENOS AIRES")
       
return direccion
   
return "Formato no soportado"
# Ejemplo
print(estandarizar_direccion("123 Main Street, Springfield, California", "EE.UU."))
# Resultado: 123 MAIN ST, SPRINGFIELD, CA

En SQL

sql

CREATE FUNCTION estandarizar_direccion(direccion TEXT, pais TEXT)
RETURNS TEXT AS $$
BEGIN
   
IF pais = 'EE.UU.' THEN
       
RETURN regexp_replace(direccion, '(STREET|AVENUE)', 'ST', 'gi');
   ELSIF pais = 'Canadá'
THEN
       
RETURN regexp_replace(direccion, '(ONTARIO|QUEBEC)', CASE WHEN $1 ~* 'ONTARIO' THEN 'ON' ELSE 'QC' END, 'gi');
   ELSIF pais = 'Argentina'
THEN
       
RETURN regexp_replace(direccion, '(CALLE|CABA)', '', 'gi');
   
ELSE
       
RETURN 'Formato no soportado';
   
END IF;
END;
$$
LANGUAGE plpgsql;
-- Ejemplo
SELECT estandarizar_direccion('123 Main Street, Springfield, California', 'EE.UU.');
-- Resultado: 123 MAIN ST, SPRINGFIELD, CA

En Power Query M

text

let
   EstandarizarDireccion = (direccion as text, pais as text) as text =>
   let
       UpperCase = Text.Upper(direccion),
       Resultado = if pais = "EE.UU." then
                       Text.Replace(UpperCase, "STREET", "ST")
                   else if pais = "Canadá" then
                       Text.Replace(UpperCase, "ONTARIO", "ON")
                   else if pais = "Argentina" then
                       Text.Replace(UpperCase, "CALLE", "")
                   else
                       "Formato no soportado"
   in
       Resultado
in
   EstandarizarDireccion
// Ejemplo de uso:
EstandarizarDireccion("123 Main Street, Springfield, California", "EE.UU.")
// Resultado: 123 MAIN ST, SPRINGFIELD, CALIFORNIA


Conclusión

La estandarización de direcciones varía significativamente entre países debido a diferencias culturales y logísticas en sus formatos. 

  • Los desafíos incluyen errores humanos y validación contra bases oficiales actualizadas. 

  • Utilizar herramientas específicas para cada país es esencial para garantizar precisión y evitar problemas logísticos.


Validación de direcciones con APIs (incluyendo coordenadas y códigos postales)

Herramientas recomendadas

API                                 Características                                       Costo

Google Maps      Validación de direcciones,                         Gratuito (100k llamadas/mes)   

                              geocodificación inversa, coordenadas

                              y códigos postales

USPS Web API    Validación de direcciones en EE.UU.,      Gratuito (requiere cuenta)

                               corrección de formatos y códigos ZIP

HERE Maps         Geocodificación y validación 

                              de direcciones globales                             Gratuito (250k llamadas/mes)


Ejemplos técnicos

1. Python (Google Maps Geocoding API)

python

import requests
def validar_direccion_google(direccion, api_key):
   url = f"https://maps.googleapis.com/maps/api/geocode/json?address={direccion}&key={api_key}"
   response = requests.get(url)
   
if response.status_code == 200:
       data = response.json()
       
if data['status'] == 'OK':
           
return {
               'valida': True,
               'componentes': data['results'][0]['address_components'],
               'coordenadas': data['results'][0]['geometry']['location'],
               'codigo_postal': next((item['long_name']
for item in data['results'][0]['address_components'] if 'postal_code' in item['types']), None)
           }
   
return {'valida': False}
# Ejemplo de uso:
direccion = "1600 Amphitheatre Parkway, Mountain View, CA"
print(validar_direccion_google(direccion, "TU_API_KEY"))

2. SQL (USPS Web API)

sql

CREATE FUNCTION validar_direccion_usps(direccion TEXT)
RETURNS JSON AS $$
DECLARE
   respuesta JSON;
BEGIN
   
SELECT content INTO respuesta FROM http_get(
       'https://secure.shippingapis.com/ShippingAPI.dll?API=CityStateLookup&XML=<CityStateLookupRequest USERID="TU_USER_ID"><ZipCode ID="0"><Address ID="0"><Address1>' || direccion || '</Address1></Address></ZipCode></CityStateLookupRequest>'
   );

    IF respuesta->>'status' = 'OK' THEN
       
RETURN json_build_object(
           'valida', TRUE,
           'ciudad', (respuesta->'CityStateLookupResponse'->'ZipCode'->'Address'->'City'),
           'estado', (respuesta->'CityStateLookupResponse'->'ZipCode'->'Address'->'State'),
           'codigo_postal', (respuesta->'CityStateLookupResponse'->'ZipCode'->'Address'->'Zip5')
       );
   
END IF;
   
RETURN json_build_object('valida', FALSE);
END;

$$
LANGUAGE plpgsql;
-- Ejemplo de uso:
SELECT validar_direccion_usps('1600 Amphitheatre Parkway, Mountain View, CA');

3. Power Query M (Google Maps Geocoding)

textlet
   ValidarDireccionGoogle = (direccion as text, api_key as text) as table =>
   let
       Url = "https://maps.googleapis.com/maps/api/geocode/json?address=" & direccion & "&key=" & api_key,
       Respuesta = Web.Contents(Url),
       Json = Json.Document(Respuesta),
       Resultado = if Json[status] = "OK" then
           Table.FromColumns({
               {Json[results]{0}[address_components]},
               {Json[results]{0}[geometry][location]},
               {List.First(List.Select(Json[results]{0}[address_components], each List.Contains(_, "postal_code")))[long_name]}
           }, {"Componentes", "Coordenadas", "Código Postal"})
       else
           Table.FromColumns({{"Dirección inválida"}}, {"Resultado"})
   in
       Resultado
in
   ValidarDireccionGoogle
// Ejemplo de uso:
ValidarDireccionGoogle("Calle Corrientes 1234, Buenos Aires", "TU_API_KEY")


Flujo de validación recomendado

  1. Validación básica:
    Verificar formato de código postal (ej: ^\d{5}(?:-\d{4})?$ para EE.UU.).
    Eliminar caracteres no alfanuméricos (#, @, etc.).

  2. Integración con APIs:
    Google Maps: Ideal para geolocalización y validación global27.
    USPS: Específico para EE.UU., con corrección automática de direcciones13.

  3. Manejo de errores:
    Si la API devuelve ZERO_RESULTS, marcar como inválida.
    Si falta código postal, usar Google Maps para inferirlo desde las coordenadas.

Limitaciones y consideraciones

  • Google Maps:
    Requiere API key (gratuita hasta 100k llamadas/mes).
    Cobertura variable en países no angloparlantes.

  • USPS:
    Solo válido para EE.UU.
    Requiere registro para obtener USER_ID.

  • HERE Maps:
    Alternativa gratuita para geocodificación inversa8.

Para implementaciones robustas, combinar múltiples APIs según el país objetivo y validar contra bases oficiales como USPS CASS o Canada Post


Validación de direcciones en Excel con Power Query

Power Query permite automatizar la validación de direcciones mediante transformaciones de datos y conexión con APIs externas. Aquí un enfoque práctico:

1. Preparación de datos

Paso 1: Crear una tabla de direcciones

textlet
   Origen = Excel.CurrentWorkbook(){[Name="TablaDirecciones"]}[Content],
   Tipo = Table.TransformColumnTypes(Origen,{{"Dirección", type text}})
in
   Tipo

2. Validación básica (sin APIs)

Ejemplo: Corrección de formatos

textlet
   Origen = Excel.CurrentWorkbook(){[Name="TablaDirecciones"]}[Content],
   // Eliminar caracteres no alfanuméricos
   Limpiar = Table.TransformColumns(Origen,{{"Dirección", each Text.Replace(_, "#", "")}}),
   // Convertir a mayúsculas
   Mayusculas = Table.TransformColumns(Limpiar,{{"Dirección", Text.Upper}})
in
   Mayusculas

3. Validación con APIs externas

Ejemplo: Google Maps Geocoding API

textlet
   Origen = Excel.CurrentWorkbook(){[Name="TablaDirecciones"]}[Content],
   // Llamar a la API para cada dirección
   LlamarAPI = Table.AddColumn(Origen, "Validación", each Json.Document(Web.Contents("https://maps.googleapis.com/maps/api/geocode/json?address=" & [Dirección] & "&key=TU_API_KEY"))),
   // Extraer resultados
   ExtraerDatos = Table.ExpandRecordColumn(LlamarAPI, "Validación", {"results"}, {"Validación.results"}),
   // Filtrar direcciones válidas
   Filtrar = Table.SelectRows(ExtraerDatos, each [Validación.results] <> null)
in
   Filtrar

4. Validación de códigos postales

Ejemplo: USPS Web API (EE.UU.)

textlet
   Origen = Excel.CurrentWorkbook(){[Name="TablaDirecciones"]}[Content],
   // Extraer código postal (ZIP)
   ExtraerZIP = Table.AddColumn(Origen, "ZIP", each Text.AfterDelimiter([Dirección], " ")),
   // Validar con USPS
   ValidarZIP = Table.AddColumn(ExtraerZIP, "Válido", each Web.Contents("https://secure.shippingapis.com/ShippingAPI.dll?API=CityStateLookup&XML=<CityStateLookupRequest USERID='TU_USER_ID'><ZipCode ID='0'><Address ID='0'><Address1>" & [ZIP] & "</Address1></Address></ZipCode></CityStateLookupResponse>"))
in
   ValidarZIP

5. Automatización con parámetros

Ejemplo: Actualización programada

textlet
   // Parámetro para fecha de actualización

    FechaActual = DateTime.Date(DateTime.LocalNow()),
   // Consulta dinámica
   Datos = Excel.CurrentWorkbook(){[Name="TablaDirecciones"]}[Content],
   // Filtrar por fecha actual
   Filtrado = Table.SelectRows(Datos, each [Fecha] = FechaActual)
in
   Filtrado

Flujo de trabajo recomendado

  1. Importar datos:
    Usar Datos > Obtener > Desde archivo > Excel para conectar tablas de direcciones24.

  2. Transformar datos:
    Limpiar caracteres especiales y unificar formatos7.

  3. Validar con APIs:
    Integrar Google Maps o USPS para verificar direcciones y códigos postales18.

  4. Cargar resultados:
    Usar Cerrar & Cargar para mostrar datos validados en una hoja2.

Ejemplo de validación completa

text

let
   Origen = Excel.CurrentWorkbook(){[Name="TablaDirecciones"]}[Content],
   // Limpiar y convertir a mayúsculas
   Preparar = Table.TransformColumns(Origen,{{"Dirección", each Text.Upper(Text.Replace(_, "#", ""))}}),
   // Validar con Google Maps
   Validar = Table.AddColumn(Preparar, "Válido", each Json.Document(Web.Contents("https://maps.googleapis.com/maps/api/geocode/json?address=" & [Dirección] & "&key=TU_API_KEY"))[results] <> null),
   // Filtrar direcciones válidas
   Filtrado = Table.SelectRows(Validar, each [Válido])
in
   Filtrado

Este enfoque permite validar direcciones en Excel de forma estructurada, integrando herramientas nativas y APIs externas para garantizar precisión.

bottom of page