如何在pandas DataFrame中从地址列提取城市及对应经纬度坐标
pandas地址列提取城市与经纬度的可行方案
场景说明
你的DataFrame中地址列格式为路名, 城市 邮编 国家(示例:King Saud Road, Al Khobar 31952 Saudi Arabia),需要拆分出城市、经纬度字段,以下是两种可直接运行的方案:
方案1:格式统一时直接拆分提取城市
如果所有地址都遵循逗号+空格分隔的固定格式,直接用pandas字符串方法拆分即可,不需要调用外部接口:
# 按逗号拆分取第二部分,去除首尾空格后再按空格拆分,排除末尾的邮编、国家字段后拼接得到城市名 df['city'] = df['address'].str.split(',').str[1].str.strip().str.split(' ').str[:-2].str.join(' ')
方案2:调用地理编码API同时获取城市+经纬度
如果地址格式不固定,或者需要精准的经纬度坐标,用geopy库调用开源地理编码服务实现批量解析:
- 先安装依赖包
pip install geopy pandas tqdm - 运行解析代码
import pandas as pd from geopy.geocoders import Nominatim from geopy.extra.rate_limiter import RateLimiter from tqdm import tqdm # 初始化地理编码器,user-agent可自定义为任意不重复的标识 geolocator = Nominatim(user_agent="custom_address_parser") # 配置请求限流,避免接口封禁,每秒最多请求1次 geocode_func = RateLimiter(geolocator.geocode, min_delay_seconds=1) # 批量解析地址,带进度条提示 tqdm.pandas(desc="地址解析进度") df['geo_result'] = df['address'].progress_apply( lambda addr: geocode_func(addr, exactly_one=True, addressdetails=True) if pd.notna(addr) else None ) # 提取目标字段 df['latitude'] = df['geo_result'].apply(lambda x: x.latitude if x else None) df['longitude'] = df['geo_result'].apply(lambda x: x.longitude if x else None) # 优先取城市字段,取不到自动降级取城镇/乡村字段 df['city'] = df['geo_result'].apply( lambda x: x.raw['address'].get('city', x.raw['address'].get('town', x.raw['address'].get('village'))) if x else None ) # 删除临时存储的完整解析结果 df = df.drop(columns=['geo_result'])
注意:免费的Nominatim服务有调用频率限制,必须保留限流配置,单日请求量过大的话建议替换为高德/谷歌地图的商用地理编码接口
自定义函数运行失败常见原因
- 未处理地址列的空值,空值传入处理函数触发报错
- 调用外部API时没有加限流逻辑,请求被服务端拒绝返回空值
- 字符串拆分时没有做边界判断,部分不符合格式的地址导致索引越界
内容的提问来源于stack exchange,提问作者R.Mohammed
相关产品推荐
相关产品推荐

