Curso
Cuando trabajas con datos del mundo real, no puedes dar por hecho que el conjunto de datos trae toda la información imprescindible para resolver tu proyecto de data science. La mayoría de las veces tienes información parcial y necesitas enriquecer los datos con variables adicionales.
Puede que el dataset incluya una dirección, pero que falten la latitud y la longitud. En ese caso, el primer paso del enriquecimiento es añadir este par de coordenadas. A este proceso de convertir una dirección en latitud y longitud lo llamamos geocodificación.
La geocodificación es clave en muchos ámbitos, como el inmobiliario, las finanzas o la logística. Sin esta técnica, no podrías analizar ni visualizar los datos en un mapa. En este tutorial vamos a hacer geocodificación en Python gracias a una librería salvavidas llamada Geopy. ¡Vamos allá!
¿Qué es la geocodificación?
La geocodificación es un proceso que convierte direcciones (como "1600 Amphitheatre Parkway, Mountain View, CA") en coordenadas geográficas (por ejemplo, latitud 37.423021 y longitud -122.083739), que puedes usar para colocar marcadores en un mapa o posicionar el mapa. Dicho de forma sencilla, es el proceso computacional de transformar la descripción de una dirección física en una ubicación sobre la superficie terrestre.
El proceso de geocodificación suele implicar la interpolación de ubicaciones espaciales, como calles o parcelas, dentro de la extensión geográfica de un mapa. Las ubicaciones resultantes se devuelven como coordenadas numéricas, adecuadas para análisis espaciales o visualización en mapas.
La geocodificación utiliza diversas fuentes de datos para convertir una dirección en una ubicación geográfica. La fuente principal es una base de datos de referencia de calles que contiene los nombres de las vías y los rangos de numeración dentro de un área o condado concreto. Otras fuentes incluyen bases de datos de códigos postales, nombres de ciudades y lugares de interés (como parques o monumentos).
La geocodificación no consiste solo en obtener coordenadas para una dirección. También se utiliza en análisis espacial, minería de datos y depuración de datos. Por ejemplo, las empresas la utilizan para analizar información demográfica y así impulsar campañas de marketing segmentadas u optimizar rutas de reparto. En el ámbito de la seguridad pública, sirve para mapear ubicaciones de incidentes de emergencia y enviar con rapidez los servicios más cercanos.
En el contexto de data science, la geocodificación es un paso crucial para crear visualizaciones geoespaciales y puede aplicarse a casos como la predicción de precios inmobiliarios, la optimización de rutas de entrega o la planificación de respuesta ante desastres.
¿Qué es Geopy?

Geopy es una librería de Python de código abierto especializada en añadir ubicación a los datos a través de una gran variedad de servicios de geocodificación, como Google Maps, OpenStreetMap y ArcGIS.
Quizá te preguntes por qué no usar directamente cada servicio de geocodificación en lugar de la librería de Python. La ventaja de Geopy es que te permite aprovechar estos servicios con muy pocas líneas de código. De hecho, Geopy implementa una clase para cada servicio, y puedes cambiar fácilmente de la API de uno a la de otro.
Proyecto práctico de geocodificación
En este artículo, vamos a analizar el dataset Canada Museum de Kaggle. Proporciona información sobre museos ubicados en Canadá. Esta recopilación de museos podría ser útil, por ejemplo, para predecir el precio de alojamientos de Airbnb en Toronto; quizá hayas observado que el alquiler de un anuncio aumenta cuanto más cerca está de puntos de interés como museos, restaurantes, cafeterías, etc.
Echémosle un vistazo al dataset:
import pandas as pd
import geopy
l_cols= ['Name','Street Address','City','State','Zipcode']
df = pd.read_csv('/kaggle/input/canada-museums/museums list CAN.csv', encoding = "ISO-8859-1",usecols=l_cols)
df = df[df.City=='Toronto']
df.head()

En este primer vistazo vemos varias columnas con información de dirección, como el nombre del museo, la dirección, la ciudad, el estado y el código postal.
Para los siguientes pasos, necesitamos una columna única que fusione la información de todas estas columnas. ¿Cómo lo hacemos? La forma más eficiente de concatenar más de dos columnas es con pandas.series.str.cat(), que nos permite especificar el separador entre columnas:
df['Country'] = 'Canada'
l_cols_concat = ['Street Address','City','State','Zipcode','Country']
df['unique_address'] = df['Name'].str.cat(others=df[l_cols_concat], sep=',',na_rep='')
df.head()

Podemos crear una variable de tipo cadena, «address1», que contenga la dirección única de la primera fila:
address1 = df['unique_address'].iloc[0]
print(address1)
# Bizune Event Gallery,452 Richmond St W,Toronto,ON,M5V 1Y1,Canada
La usaremos en los próximos pasos para probar distintos servicios de geocodificación sobre una única dirección. Una vez veas cómo extrae Geopy la ubicación, podrás extenderlo a toda una columna de un dataframe de pandas. Probaremos los siguientes proveedores principales:
- Google Maps
- OpenStreetMap
- ArcGIS
Geocodificación con la API de Google Maps
El método más popular para convertir direcciones en coordenadas es usar la API de Google Maps.
Aunque Google Maps ofrece servicios de pago, te da 200 $ en créditos gratuitos la primera vez que creas la cuenta.
Para acceder al servicio, tienes que crear una cuenta en la Google Maps Platform. Aquí tienes un gran tutorial para generar la clave de API.
GM_API_KEY = 'your_api_key'
from geopy.geocoders import GoogleV3
geolocator = GoogleV3(api_key=GM_API_KEY)
GoogleV3 es la clase implementada para usar la API de Google Maps v3. Primero, probamos a extraer la ubicación de una sola dirección:
location = geolocator.geocode(address1)
print('Latitude: '+str(location.latitude)+', Longitude: '+str(location.longitude))

Después podemos extender esta operación al campo unique_address que hemos creado antes.
def service_geocode(g_locator, address):
location = g_locator.geocode(address)
if location!=None:
return (location.latitude, location.longitude)
else:
return np.NaN
Podemos usar apply() para aplicar la función a todas las filas de unique_address:
df['LAT_LON'] = df['unique_address'].apply(lambda x:service_geocode(geolocator,x))
df[['unique_address','LAT_LON']].head()

Geocodificación con la API de OpenStreetMap
Como OpenStreetMap es la mayor base de datos geográfica libre y editable, su API es gratuita. Para geolocalizar una única dirección, basta con proporcionar el email de tu cuenta de OSM como entrada a la clase Nominatim, en lugar de una clave de API:
from geopy.geocoders import Nominatim
geolocator = Nominatim(user_agent="your_email")
location = geolocator.geocode(address1)
print(location)
# None
Por desgracia, la ubicación que devuelve la API de OpenStreetMap es None porque no reconoce la dirección.
De hecho, a esta API le cuesta localizar muchas de las direcciones postales del dataset porque no tiene buena cobertura en todas las zonas.
Por ello, necesitamos crear otro campo, unique_address_osm, con menos información:
l_cols_concat = ['City','State','Country']
df['unique_address_osm'] = df['Street Address'].str.cat(others=df[l_cols_concat], sep=',',na_rep='')
address1_osm = df['unique_address_osm'].iloc[0]
Después pasamos la nueva dirección y volvemos a intentar extraer la latitud y la longitud a partir de la dirección:
address1_osm = df['unique_address_osm'].iloc[0]
location = geolocator.geocode(address1_osm)
print('Latitude: '+str(location.latitude)+', Longitude: '+str(location.longitude))

Como antes, aplicamos la función service_geocode() a toda la columna unique_address_osm:
df['LAT_LON_osm'] = df['unique_address_osm'].apply(lambda x: service_geocode(geolocator,x))
df[['unique_address_osm','LAT_LON','LAT_LON_osm']].head()

Aunque no indicamos el nombre del museo, OpenStreetMap devuelve coordenadas muy similares a las de Google Maps API.
Geocodificación con la API de ArcGIS
ArcGIS es un software que permite analizar y visualizar datos geoespaciales. También ofrece servicios de ubicación, como Google Maps y OpenStreetMap.
from geopy.geocoders import ArcGIS
geolocator_arcgis = ArcGIS()
location = geolocator_arcgis.geocode(address1)
print('Latitude: '+str(location.latitude)+', Longitude: '+str(location.longitude))

Esta vez no hay problema para obtener el par de coordenadas. Podemos extender la operación a todas las direcciones:
df['LAT_LON_arcgis'] = df['unique_address'].apply(lambda x: service_geocode(geolocator_arcgis,x))
df[['unique_address','LAT_LON','LAT_LON_osm','LAT_LON_arcgis']].head()

Si miramos las primeras filas del dataset, vemos que el par de coordenadas obtenido con ArcGIS es similar a los anteriores, con una ligera diferencia.
Medir la distancia entre dos lugares
Otra funcionalidad de Geopy es que nos permite calcular la distancia entre dos puntos. Esto es posible usando la distancia geodésica obtenida entre dos pares (latitud, longitud).
from geopy.distance import geodesic
point1 = df.LAT_LON_arcgis.iloc[0]
point2 = df.LAT_LON_arcgis.iloc[1]
distance = geodesic(point1, point2)
print('The distance between {} and {} is {} meters'.format(df.Name.iloc[0],df.Name.iloc[1],distance.meters))

La distancia entre estos dos museos es de aproximadamente 2 kilómetros.
Conclusiones
¡Listo! Has aprendido tres formas distintas de convertir una dirección en latitud y longitud con Geopy. Este es un punto de partida para análisis geoespaciales más avanzados y complejos.
Si te interesa empezar con el análisis geoespacial sin código, lo mejor es que eches un vistazo al tutorial de DataCamp Working with Geospatial Data: A Guide to Analysis in Power BI.
Para crear visualizaciones y cálculos más avanzados, Tableau puede ser la herramienta perfecta para ti. El curso de DataCamp Introduction to Tableau te permitirá crear visualizaciones dinámicas y resolver cualquier problema analítico.
Si eres fan del lenguaje R, este gran curso te enseña a crear mapas interactivos con leaflet. Si te mantienes fiel a Python, plantéate hacer Visualizing geospatial data in Python, que te ayudará a crear visualizaciones potentes con geopandas y folium.
