Direcciones postales
Estandarización de direcciones postales

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
Extracción/parsing: Separar direcciones no estructuradas en componentes
Corrección: Aplicar reglas de normalización
Enrichment: Complementar información faltante
Geolocalización: Agregar coordenadas
Verificación: Contrastar con fuentes oficiales
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:
Calle
Número
Complementos: (Piso, Depto)
BarrioYUrbanización
Ciudad/Departamento/Localidad
Provincia/Estado
Código Postal
3. Validación contra fuentes externas
Bases de referencia:
Catastro municipal: Verificar existencia de calles y números.
Servicios postales: Confirmar códigos postales y su relación con ciudades.
Registros de propiedades: Cruzar con direcciones registradas.
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:
URBANIZACION
→URB.
oURBANIZACIÓN
.Consistencia numérica:
#12-45
→12-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
Preprocesamiento:
python
# Eliminar diacríticos y caracteres especiales
direccion_limpia = unicodedata.normalize('NFKD', direccion).encode('ASCII', 'ignore').decode()
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}';
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
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.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.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.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.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
Validación básica:
Verificar formato de código postal (ej:^\d{5}(?:-\d{4})?$
para EE.UU.).
Eliminar caracteres no alfanuméricos (#
,@
, etc.).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.Manejo de errores:
Si la API devuelveZERO_RESULTS
, marcar como inválida.
Si falta código postal, usarGoogle 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 obtenerUSER_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
Importar datos:
UsarDatos > Obtener > Desde archivo > Excel
para conectar tablas de direcciones24.Transformar datos:
Limpiar caracteres especiales y unificar formatos7.Validar con APIs:
Integrar Google Maps o USPS para verificar direcciones y códigos postales18.Cargar resultados:
UsarCerrar & 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.