Geopy Nominatim读取CSV院校地址报错,手动输入正常如何解决?
问题解决思路与代码修正
核心问题分析
你遇到的问题主要出在两个方面:
- CSV读取后的数据可能存在异常(比如空值、字符串前后空格、隐藏换行符),导致地址解析失败
- 异常处理范围错误:原代码的
try-except包裹了整个apply操作,只要有一个地址解析失败,就会把整列location设为not found,而不是单独处理错误的地址
分步解决方案
1. 先验证CSV读取的数据有效性
读取CSV后先检查数据格式,确保和手动输入的内容一致:
import pandas as pd from geopy.geocoders import Nominatim # 初始化地理编码器 geolocator = Nominatim(user_agent='ryan-data') # 读取CSV文件(替换为你的文件路径) df = pd.read_csv('schools.csv') # 检查列名是否正确,确保存在'school'列 print("列名检查:", df.columns.tolist()) # 查看前几行数据,确认地址内容 print("数据预览:") print(df.head()) # 检查是否有空值 print("空值数量:", df['school'].isnull().sum()) # 清理地址字符串:去除前后空格、换行符等 df['school'] = df['school'].str.strip().str.replace('\n', '')
2. 修正异常处理逻辑(单个地址单独处理)
把异常处理放到单个地址的解析函数中,避免一个错误影响整列:
def get_geolocation(school_name): # 先判断输入是否为空 if pd.isnull(school_name) or school_name.strip() == '': return 'empty input' try: # 尝试解析地址 return geolocator.geocode(school_name) except Exception as e: # 打印错误信息方便排查 print(f"解析失败 {school_name}: {str(e)}") return 'not found' # 批量解析地址 df['location'] = df['school'].apply(get_geolocation)
3. 规避Nominatim请求限制
Nominatim有请求速率限制,频繁请求会被拒绝,建议添加请求延迟:
from geopy.extra.rate_limiter import RateLimiter # 给解析请求添加1秒延迟,避免触发限制 geocode_with_delay = RateLimiter(geolocator.geocode, min_delay_seconds=1) # 使用带延迟的解析函数 df['location'] = df['school'].apply( lambda x: geocode_with_delay(x) if pd.notnull(x) and x.strip() != '' else 'invalid input' )
额外提示
- 如果CSV中的地址列名不是
school,请在读取时用pd.read_csv('file.csv', names=['school'])指定列名 - 解析后的
location是Location对象,可以提取经纬度:df['latitude'] = df['location'].apply(lambda x: x.latitude if x != 'not found' else None)
内容的提问来源于stack exchange,提问作者ASH
相关产品推荐
相关产品推荐

