You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现地址转经纬度时复用已有坐标,避免重复调用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)

代码说明

  1. 缓存字典address_coords:存储每个唯一地址对应的经纬度,确保每个地址只调用一次geolocator.geocode()。
  2. 遍历唯一地址:通过df['address'].unique()获取不重复的地址列表,批量查询并填充缓存。
  3. 映射回原DataFrame:用map方法将缓存中的坐标快速关联到原数据的每一行,避免逐行调用接口。

内容的提问来源于stack exchange,提问作者Test

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 20:51:13