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

遍历Pandas DataFrame用geopy逆地理编码获州信息遇错求助

问题解决

第一个错误:ValueError: Must be a coordinate pair or Point

你的遍历逻辑完全错误,for row in df 遍历的是DataFrame的列名,不是每一行数据。所以str(df['latitude'])拿到的是整列纬度的字符串(类似0 38.0525\n1 40.7128\nName: latitude, dtype: object),不是单个有效坐标,传给reverse自然触发格式错误。

修正遍历方式

放弃for row in df的写法,改用df.apply()处理每一行(更符合Pandas操作风格),或使用iterrows()时正确提取单行数据(但apply效率更高)。

第二个错误:GeocoderTimedOut

Nominatim有严格的请求频率限制(非商业用途要求至少1秒间隔),批量请求不加延迟会被服务器拒绝,导致超时。另外,每次循环初始化Nominatim实例完全没必要,应该只初始化一次。

完整修正代码

import pandas as pd
from geopy.geocoders import Nominatim
from geopy.exc import GeocoderTimedOut, GeocoderUnavailable
import time

# 只初始化一次geolocator,避免重复创建连接
geolocator = Nominatim(user_agent='geoapiExercises')

def get_state(row):
    # 提前处理空值或无效坐标
    if pd.isna(row['latitude']) or pd.isna(row['longitude']):
        return ''
    
    try:
        # 直接传坐标元组,比拼接字符串更可靠
        location = geolocator.reverse((row['latitude'], row['longitude']), timeout=10)
        if location and 'address' in location.raw:
            return location.raw['address'].get('state', '')
        return ''
    except (GeocoderTimedOut, GeocoderUnavailable):
        # 超时或服务不可用时,重试一次
        time.sleep(2)
        try:
            location = geolocator.reverse((row['latitude'], row['longitude']), timeout=10)
            return location.raw['address'].get('state', '') if location else ''
        except (GeocoderTimedOut, GeocoderUnavailable):
            return '获取失败'
    finally:
        # 强制添加1秒延迟,遵守Nominatim的使用规则
        time.sleep(1)

# 读取数据并筛选美国数据
df = pd.read_csv('filepath.csv')
us_df = df.loc[df['country_name'] == 'United States of America'].copy()

# 应用函数生成state列
us_df['state'] = us_df.apply(get_state, axis=1)

# 保存结果(可选)
us_df.to_csv('us_data_with_state.csv', index=False)

关键修正点

  • 单次初始化geolocator:避免重复创建客户端,提升请求效率。
  • 用apply处理每行:符合Pandas向量化操作逻辑,比iterrows更高效。
  • 坐标传元组:reverse支持直接传入(lat, lon)元组,避免字符串拼接出错。
  • 异常捕获:处理超时、服务不可用的情况,防止程序中断。
  • 强制延迟:每次请求后休眠1秒,严格遵守Nominatim的使用限制,避免被封禁。
  • 空值预处理:提前过滤无效坐标,减少不必要的请求。

额外建议

如果数据量较大(10000条),可以考虑:

  • 用geopy.extra.rate_limiter.RateLimiter替代手动time.sleep,更灵活控制请求频率。
  • 对已获取的结果做缓存,避免重复请求相同坐标。

内容的提问来源于stack exchange,提问作者Exquisite_Poupon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 06:30:53