遍历NumPy数组的最快方法?如何向量化调用geopy的geodesic函数
解决方案
geopy 自带的 geodesic 方法本身不支持直接传入 NumPy 数组进行批量计算,下面提供两种满足需求的实现方式:
方案1:无显式for循环的语法简化实现
用 np.vectorize 封装函数,写法上符合你期望的无显式循环的调用形式,不需要手动写迭代逻辑:
import numpy as np from geopy.distance import geodesic lat_start = 48.778767 long_start = -123.903275 bearing = 39.060744 coords1 = (lat_start, long_start) D = np.array([ 0. , 60.00501526, 120.01003051, 180.01504577, 240.02006102, 300.02507628, 360.03009153, 420.03510679, 480.04012205, 540.0451373 ]) # 封装单个距离对应的目标点计算逻辑 def calc_single_dest(d): return geodesic(kilometers=d/1000).destination(coords1, bearing) # 向量化封装后直接传入数组即可得到批量结果 vec_calc = np.vectorize(calc_single_dest) destination = vec_calc(D)
注意:np.vectorize 本质是语法糖,底层还是遍历执行循环,速度相比手写for循环只有小幅提升,如果需要数量级的速度提升可以用方案2。
方案2:JIT编译循环实现(速度提升10~100倍)
如果可以安装numba库,用JIT编译循环逻辑可以实现接近原生C的执行速度,处理万级以上元素也没有压力:
import numpy as np from numba import jit from geographiclib.geodesic import Geodesic lat_start = 48.778767 long_start = -123.903275 bearing = 39.060744 D = np.array([ 0. , 60.00501526, 120.01003051, 180.01504577, 240.02006102, 300.02507628, 360.03009153, 420.03510679, 480.04012205, 540.0451373 ]) D_km = D / 1000 @jit(nopython=True) def calc_batch_dest(dist_arr, start_lat, start_lon, bearing): res = np.zeros((len(dist_arr), 2)) geod = Geodesic.WGS84 for i in range(len(dist_arr)): # geographiclib距离单位为米,做单位转换 g = geod.Direct(start_lat, start_lon, bearing, dist_arr[i] * 1000) res[i, 0] = g['lat2'] res[i, 1] = g['lon2'] return res # 输出结果为N行2列的数组,每行对应一个距离的纬度、经度 destination = calc_batch_dest(D_km, lat_start, long_start, bearing)
这个方案用了geopy底层依赖的geographiclib原生接口,配合numba编译后速度极快,完全满足大批量数据的计算需求。
内容的提问来源于stack exchange,提问作者Cheeta_2019
相关产品推荐
相关产品推荐

