如何从DataFrame地址列获取经纬度?解决指定代码报错问题
解决Geopy地址解析报错"method object is not subscriptable"的方案
嘿,我刚帮你排查了代码里的问题,报错method object is not subscriptable的根源是你调用apply时没传入正确的处理函数,而且还没把Geopy的地理编码功能用限速器包装起来,导致后续代码根本没拿到有效的地址解析结果。
错误原因拆解
你写的这一行:
results['location']=results['Details'].apply
这里apply只是引用了方法本身,没有传入要执行的地理编码函数,所以results['location']里存的是apply方法对象,而不是地址解析后的Location实例,后面用lambda loc:tuple(loc['point'])访问时自然就会报错“方法对象不能被下标访问”。
正确的批量解析方案(推荐用RateLimiter+Apply)
Geopy的Nominatim有请求频率限制,必须用RateLimiter包装geocode方法,避免被封禁。下面是完整的修正代码:
import pandas as pd from geopy.geocoders import Nominatim from geopy.extra.rate_limiter import RateLimiter # 初始化定位器,记得设置自己的user_agent(可以是你的项目名称) locator = Nominatim(user_agent="MyGeocoder_Project") # 用RateLimiter包装geocode方法,设置最小请求间隔1秒,避免触发限制 geocode = RateLimiter(locator.geocode, min_delay_seconds=1) # 批量解析地址,得到Location对象(解析失败会返回None) results['location'] = results['Details'].apply(geocode) # 从Location对象中提取经纬度元组,处理解析失败的情况 results['point'] = results['location'].apply(lambda loc: loc.point[:2] if loc else None) # 将元组拆分为单独的Latitude和Longitude列 results[['Latitude', 'Longitude']] = pd.DataFrame(results['point'].tolist(), index=results.index)
如果你想用循环实现批量解析
虽然apply已经很方便,但如果偏好循环写法,也可以这样做(同样要加延迟遵守规则):
import time import pandas as pd from geopy.geocoders import Nominatim locator = Nominatim(user_agent="MyGeocoder_Project") # 初始化经纬度列 results['Latitude'] = None results['Longitude'] = None # 遍历每一行处理地址 for idx, row in results.iterrows(): address = row['Details'] try: location = locator.geocode(address) if location: results.at[idx, 'Latitude'] = location.latitude results.at[idx, 'Longitude'] = location.longitude # 每次请求后暂停1秒,遵守Nominatim的使用规则 time.sleep(1) except Exception as e: print(f"解析地址{address}时出错:{e}") continue
注意事项
- 一定要设置合理的
user_agent,不能用默认值,否则可能被Nominatim拒绝服务 - 保持请求间隔至少1秒,这是Nominatim的官方要求
- 部分地址可能解析失败(比如格式不规范、地址不存在),所以一定要处理
None的情况,避免报错
内容的提问来源于stack exchange,提问作者AmyZK
相关产品推荐
相关产品推荐

