如何使用pgeocode加速大型dataframe的邮政编码经纬度查询?
问题分析
- 重复实例化开销:每次调用经纬度查询函数时,都会重新创建
pgeocode.Nominatim对象,10万行数据会产生数十万次不必要的实例化操作,占了大部分耗时 - 重复查询开销:同一个邮政编码+国家编码组合会被查询2次,分别获取纬度和经度,查询次数直接翻倍
- 循环效率低下:用
np.vectorize本质还是逐行调用函数,没有用到pgeocode自带的批量查询能力,效率极低
优化方案
核心思路是用向量化批量操作替代逐行循环,消除所有冗余开销:
- 按国家分组处理,每个国家仅初始化1次
pgeocode.Nominatim对象 - 每个国家的所有邮政编码一次性批量查询,一次就能拿到全部地址的经纬度数据
- 直接批量赋值到新增列,无需逐行处理和重复查询
优化后代码
import pgeocode import numpy as np import pandas as pd # 样例数据 df = pd.DataFrame({'postcode':['3011','3083','3071','2660','9308','9999'], 'country_code': ['NL','NL','NL','BE','BE','DE']}) # 初始化经纬度列为空值 df['latitude'] = np.nan df['longitude'] = np.nan # 按国家分组批量查询 for country, group in df.groupby('country_code'): # 每个国家仅初始化一次Nominatim nomi = pgeocode.Nominatim(country) # 批量查询当前国家的所有邮编 query_res = nomi.query_postal_code(group['postcode'].tolist()) # 批量赋值经纬度到对应行 df.loc[group.index, 'latitude'] = query_res['latitude'].values df.loc[group.index, 'longitude'] = query_res['longitude'].values
效果说明
原有10万行数据超过1小时的运行任务,优化后通常可以在10秒内完成,同时查询结果和原有逻辑完全一致,查不到的邮政编码会自动填充NaN,无需额外写异常捕获逻辑。
内容的提问来源于stack exchange,提问作者volkan g
相关产品推荐
相关产品推荐

