如何提升基于大地距离合并两个DataFrame的性能?
基于大地距离匹配DataFrame数据的性能优化
问题背景
我拥有两个DataFrame:
radar:代表等间距网格数据,包含longitude、latitude和height列ice:存储卫星观测相关信息,包含观测点的latitude和longitude
需求是:基于每个ice行到最近radar点的大地距离,将radar中的height列合并到ice中。
原始实现(性能极差)
最初使用geopy的geodesic函数计算距离,代码如下:
from geopy.distance import geodesic import pandas as pd def get_distance(out): global radar dists = radar['latlon'].apply(lambda x: geodesic(out['latlon'], x).km) out['dist to radar']=min(dists) out['rate_yr_radar']=radar.loc[dists.idxmin()]['rate_yr_radar'] return out ICEvsRadar=ice.apply(get_distance, axis=1)
性能表现:当ice为180行、radar为50000行时,运行耗时约30分钟。
性能疑问
这种慢性能是计算每个距离的固有成本导致,还是可以通过优化实现方式来提升?
优化方案(性能大幅提升)
借助建议改用sklearn的BallTree实现最近邻查询,代码如下:
import pandas as pd import numpy as np from sklearn.neighbors import BallTree # 构建BallTree(需先将经纬度转换为弧度) Tree = BallTree(np.deg2rad(radar[['lat', 'lon']].values), metric='haversine') # 查询每个ice点的最近radar点,返回距离和索引 distance, index = Tree.query(np.deg2rad(ice.loc[:, ["lat","lon"]])) # 提取radar中匹配的数据并处理距离单位 reduced_radar = radar.loc[np.concatenate(index), ["rate_yr_radar"]] reduced_radar['dist to radar']=np.concatenate(distance)*6371 # 转换为公里(地球半径约6371km) reduced_radar = reduced_radar.reset_index().rename({"index": "index_from_radar"}, axis=1) # 将匹配结果合并到ice ice = ice.join(reduced_radar)
性能表现:运行耗时从30分钟缩短至60毫秒!
内容的提问来源于stack exchange,提问作者Feva
相关产品推荐
相关产品推荐

