如何实现地址转经纬度时复用已有坐标,避免重复调用geocode接口?
解决重复地址重复调用地理编码接口的问题
需求:从地址提取经度(long)与纬度(lat)坐标,当前代码可实现转换,但重复地址会重复调用geolocator.geocode()接口,需优化为:判断地址是否已有经纬度值,有则直接复用,避免重复查询。
原始DataFrame
address customer 0 Surlej, 7513, Silvaplana, Schweiz 1 1 Vodnikova cesta 35, 1000 Ljubljana, Slowenien 2 2 Surlej, 7513, Silvaplana, Schweiz 1
现有代码(存在重复调用问题)
import pandas as pd d = { "address": ['Surlej, 7513, Silvaplana, Schweiz', 'Vodnikova cesta 35, 1000 Ljubljana, Slowenien', 'Surlej, 7513, Silvaplana, Schweiz',], "customer": [1, 2, 1], } df = pd.DataFrame(data=d) print(df) from geopy.geocoders import Nominatim geolocator = Nominatim(user_agent='testing_stackoverflow') def adressToLatLong(df): location = geolocator.geocode(df['address']) #print(location) if (location == None): df['address'] = None df['address'] = None else: df['latitude'] = location.latitude df['longitude'] = location.longitude return df df = df.apply(lambda x: adressToLatLong(x), axis=1)
预期输出
address customer latitude 0 Surlej, 7513, Silvaplana, Schweiz 1 46.459902 1 Vodnikova cesta 35, 1000 Ljubljana, Slowenien 2 46.065523 2 Surlej, 7513, Silvaplana, Schweiz 1 46.459902 longitude 0 9.803370 1 14.490775 2 9.803370
尝试的失败方案
尝试用字典存储已查询的地址与坐标,但返回空字典,未达到预期:
def adressToLatLong(addresses): adresses_new = {} for address in addresses: location = geolocator.geocode(df['address']) #print(location) if (location == None): df['address'] = None df['address'] = None else: adresses_new.update({'adress': address, 'long': location.longitude, 'lat': location.latitude}) return adresses_new adressToLatLong(df['address'].unique()) [OUT] {}
正确解决方案
核心思路是用字典缓存已查询的地址-坐标映射,只对唯一地址调用一次地理编码接口,再将映射结果批量关联回原DataFrame,避免重复调用。
完整优化代码
import pandas as pd from geopy.geocoders import Nominatim # 初始化数据 d = { "address": ['Surlej, 7513, Silvaplana, Schweiz', 'Vodnikova cesta 35, 1000 Ljubljana, Slowenien', 'Surlej, 7513, Silvaplana, Schweiz',], "customer": [1, 2, 1], } df = pd.DataFrame(data=d) # 初始化地理编码工具 geolocator = Nominatim(user_agent='testing_stackoverflow') # 创建缓存字典,存储已查询的地址与坐标 address_coords = {} # 遍历所有唯一地址,只查询一次 for address in df['address'].unique(): location = geolocator.geocode(address) if location: address_coords[address] = {'latitude': location.latitude, 'longitude': location.longitude} else: address_coords[address] = {'latitude': None, 'longitude': None} # 将缓存的坐标映射回原DataFrame df['latitude'] = df['address'].map(lambda x: address_coords[x]['latitude']) df['longitude'] = df['address'].map(lambda x: address_coords[x]['longitude']) print(df)
代码说明
- 缓存字典
address_coords:存储每个唯一地址对应的经纬度,确保每个地址只调用一次geolocator.geocode()。 - 遍历唯一地址:通过
df['address'].unique()获取不重复的地址列表,批量查询并填充缓存。 - 映射回原DataFrame:用
map方法将缓存中的坐标快速关联到原数据的每一行,避免逐行调用接口。
内容的提问来源于stack exchange,提问作者Test
相关产品推荐
相关产品推荐

