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

基于Python Pandas DataFrame并行化逆地理编码函数的实现需求

嘿,我来帮你搞定这个并行逆地理编码的需求!咱们一步步来,从选工具到写代码,再到避坑提示都安排得明明白白。

第一步:准备依赖库

首先得装好用的逆地理编码工具,这里推荐用geopy(免费且易用),再加上你已经在用的pandas:

pip install geopy pandas

multiprocessing是Python标准库,不用额外安装。

第二步:写单个经纬度的逆地理编码函数

先写一个处理单组经纬度的核心函数,要考虑请求失败、地址字段兼容这些细节:

from geopy.geocoders import Nominatim
from geopy.exc import GeocoderTimedOut, GeocoderUnavailable
import time

def get_city_from_coords(lat_lon):
    # 必须设置user_agent,不然Nominatim会拒绝请求(随便填个你的应用名就行)
    geolocator = Nominatim(user_agent="my_city_geocoder")
    lat, lon = lat_lon
    
    try:
        # 逆地理编码,指定返回地址详情,方便提取城市
        location = geolocator.reverse((lat, lon), exactly_one=True, addressdetails=True)
        if not location:
            return None
        
        # 不同地区的地址字段可能不同,多做几个备选兼容
        address = location.raw['address']
        city = (
            address.get('city') 
            or address.get('town') 
            or address.get('municipality') 
            or address.get('village')
            or None
        )
        return city
    except (GeocoderTimedOut, GeocoderUnavailable):
        # 网络超时或服务不可用时,重试一次(加个延迟避免频繁请求)
        time.sleep(2)
        return get_city_from_coords(lat_lon)
    except Exception as e:
        print(f"处理经纬度({lat}, {lon})时出错: {str(e)}")
        return None

关键细节:

  • 每个进程单独初始化Nominatim对象,避免进程间的资源冲突
  • 兼容不同地区的地址字段(比如国内城市用city,小镇可能用town)
  • 加重试机制应对网络波动
第三步:用multiprocessing实现并行处理

接下来把你的numpy经纬度数组转成可迭代的元组列表,再用进程池并行处理:

import pandas as pd
import numpy as np
from multiprocessing import Pool

if __name__ == "__main__":
    # 假设你已经有了包含经纬度的DataFrame(替换成你的实际df)
    df = pd.DataFrame({
        'latitude': [39.9042, 31.2304, 23.1291],
        'longitude': [116.4074, 121.4737, 113.2644]
    })
    
    # 你已经切片好的numpy数组(直接用你自己的coords_array就行)
    coords_array = df[['latitude', 'longitude']].to_numpy()
    # 转成元组列表,方便multiprocessing的map处理
    coords_list = list(map(tuple, coords_array))
    
    # 设置进程数:别贪多!Nominatim免费版限制每秒1次请求,建议设4-8个
    num_processes = 4
    
    # 创建进程池并行处理
    with Pool(num_processes) as pool:
        city_results = pool.map(get_city_from_coords, coords_list)
    
    # 把结果赋值给city列
    df['city'] = city_results
    
    # 可选:填充无法解析的空值
    df['city'] = df['city'].fillna('未知城市')
    
    # 查看最终结果
    print(df)

Windows用户注意:必须把主逻辑放在if __name__ == "__main__":块里,不然会触发multiprocessing的重复进程创建bug。

第四步:避坑关键提示
  • Nominatim请求限制:免费版严格限制每秒1次请求,如果进程数太多,会被临时封禁IP。要么降低进程数,要么在get_city_from_coords函数末尾加time.sleep(1)强制延迟。
  • 数据量太大?用imap加进度条:如果你的经纬度数据有上万条,可以用tqdm显示处理进度:
    from tqdm import tqdm
    
    with Pool(num_processes) as pool:
        city_results = list(tqdm(pool.imap(get_city_from_coords, coords_list), total=len(coords_list)))
    
  • 隐私与合规:如果是商业用途,建议用付费的逆地理编码服务(比如高德、百度地图的API),免费的Nominatim有使用限制,且数据更新可能不及时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:39:37