使用Geopy转换邮编后无法将经纬度添加至Pandas DataFrame求助
问题分析与解决步骤
你的代码存在几个关键问题导致无法正常运行,以下是具体修正方向:
1. 未初始化地理定位器实例
代码中直接调用geolocator.geocode,但没有先创建Nominatim的实例对象。Nominatim要求必须设置user_agent(标识请求来源,避免被API限制),初始化方式如下:
geolocator = Nominatim(user_agent="你的实习项目名称或邮箱前缀")
2. 未处理地理编码失败的情况
部分邮编可能无法被解析,此时geocode()会返回None,直接调用x.latitude会触发AttributeError。需要先判断结果是否存在:
sales['co-ordinates'] = sales['postcode'].apply(geolocator.geocode).apply( lambda x: (x.latitude, x.longitude) if x is not None else (None, None) )
3. 规避API请求限制
Nominatim对请求频率有严格限制(默认1秒最多1次请求),批量处理大量邮编时容易被封禁。可以用geopy的RateLimiter控制请求速度:
from geopy.extra.rate_limiter import RateLimiter # 包装geocode方法,设置延迟 geocode = RateLimiter(geolocator.geocode, min_delay_seconds=1) # 先获取地理编码结果 sales['location'] = sales['postcode'].apply(geocode) # 再提取经纬度 sales['co-ordinates'] = sales['location'].apply( lambda x: (x.latitude, x.longitude) if x is not None else (None, None) )
完整修正后的代码示例
import pandas as pd from geopy.geocoders import Nominatim from geopy.extra.rate_limiter import RateLimiter # 初始化定位器,替换user_agent为你的标识 geolocator = Nominatim(user_agent="intern_postcode_geocoding") # 控制请求频率 geocode = RateLimiter(geolocator.geocode, min_delay_seconds=1) sales = pd.read_csv('file_path/ppd_data.csv') # 获取地理编码结果 sales['location'] = sales['postcode'].apply(geocode) # 提取经纬度,处理解析失败的情况 sales['co-ordinates'] = sales['location'].apply( lambda x: (x.latitude, x.longitude) if x is not None else (None, None) ) # 查看结果 print(sales.head())
额外提示
- 对于英国土地登记处的邮编数据,确保邮编格式正确(如是否包含空格的标准格式
SW1A 1AA),格式错误会导致解析失败。 - 如果批量数据量极大,建议考虑使用付费地理编码API,稳定性和处理速度会更优。
内容的提问来源于stack exchange,提问作者DLR
相关产品推荐
相关产品推荐

