如何用Python快速为海量美国经纬度CSV数据匹配对应州名?
美国经纬度批量匹配州名高效处理方案
原方案低效原因
Nominatim属于在线逆地理编码服务,存在严格的请求频率限制,且单次请求仅能处理单个坐标点,400万条数据的网络请求开销就占了绝大多数耗时,完全不适合这类特定区域的批量坐标匹配场景。
推荐方案:离线空间索引匹配
基于美国州边界矢量文件和空间索引做离线批量匹配,单文件处理耗时可从数小时压缩到分钟级,支持循环批量处理所有CSV文件。
前置依赖
提前安装所需Python库:
pip install geopandas pandas shapely rtree
提前准备美国各州边界矢量文件,也可直接使用geopandas内置的公开美国边界数据。
核心实现步骤
- 仅执行一次的预加载操作:读取美国州边界矢量数据,构建空间索引,避免重复加载浪费资源
- 循环遍历所有待处理CSV文件
- 单文件处理时分块读取数据,避免大文件一次性加载撑爆内存
- 把经纬度转成空间点对象,通过空间索引批量匹配对应州的边界,直接提取州名
- 把州名列追加到原数据后,分块写入输出文件
示例代码
import geopandas as gpd import pandas as pd from shapely.geometry import Point # 预加载美国州边界、构建空间索引,仅执行一次 us_states = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres')) us_states = us_states[us_states.iso_a3 == 'USA'][['name', 'geometry']].rename(columns={'name': 'state_name'}) state_spatial_index = us_states.sindex # 循环处理400个有序命名的CSV文件,假设文件命名规则为 data_001.csv ~ data_400.csv for file_seq in range(1, 401): input_file = f"data_{file_seq:03d}.csv" output_file = f"data_{file_seq:03d}_with_state.csv" # 分块读取,chunksize可根据自身内存大小调整,100万条约占用数百MB内存 for chunk in pd.read_csv(input_file, chunksize=1000000): # 把经纬度转为空间点对象,坐标系用标准WGS84即EPSG:4326 point_gdf = gpd.GeoDataFrame( chunk, geometry=gpd.points_from_xy(chunk.longitude, chunk.latitude), crs="EPSG:4326" ) # 批量空间匹配:判断点落在哪个州的边界范围内 matched_result = gpd.sjoin(point_gdf, us_states, how='left', predicate='within') # 追加州名列,删除多余的空间字段 chunk['state_name'] = matched_result['state_name'] chunk = chunk.drop(columns=['geometry'], errors='ignore') # 写入输出文件:第一个分块写表头,后续分块直接追加 chunk.to_csv( output_file, mode='a', index=False, header=not pd.io.common.file_exists(output_file) ) print(f"文件{input_file}处理完成")
注意事项
- 请将代码中的经纬度字段名
longitudelatitude替换为你CSV中实际对应的字段名 - 若坐标点位于美国境外/公海等无对应州的区域,
state_name会返回空值,可根据自身需求后续处理 - 若内存足够大可调大
chunksize,也可引入多进程同时处理多个CSV文件,效率可再提升数倍
内容的提问来源于stack exchange,提问作者Abhay Tyagi
相关产品推荐
相关产品推荐

