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

Geopy Nominatim读取CSV院校地址报错,手动输入正常如何解决?

问题解决思路与代码修正

核心问题分析

你遇到的问题主要出在两个方面:

  1. CSV读取后的数据可能存在异常(比如空值、字符串前后空格、隐藏换行符),导致地址解析失败
  2. 异常处理范围错误:原代码的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 17:12:45