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

Pandas经纬度计算最近零售门店:替代逐行迭代的向量化方案

房屋匹配最近超市的代码性能优化方案

原有代码的核心性能瓶颈

  • 逐行调用iterrows()遍历DataFrame属于pandas低性能操作,逐行用.at()赋值会频繁触发DataFrame元数据更新,额外开销远大于计算本身
  • 每次循环都覆写超市数据集的dis_from_house列,重复修改表结构产生大量无意义消耗
  • 纯Python层面的双重循环计算距离,没有利用批量计算的性能优势

方案1:最小改动版(保留原有距离计算逻辑,性能提升3~10倍)

不需要替换你已经在使用的测地线距离计算逻辑,只需要把循环内的DataFrame操作全部移到循环外,用列表收集结果后一次性赋值,避免循环内修改表结构:

from geopy.distance import geodesic

# 提前把超市的坐标、品牌转成原生Python列表,减少循环内pandas取值开销
supermarket_locs = list(zip(adjusted_supermarket_df['lat_wgs'], adjusted_supermarket_df['long_wgs']))
supermarket_brands = adjusted_supermarket_df['retailer'].tolist()
match_result = []
total_count = len(small_housing_df)

# 直接zip遍历经纬度列,比iterrows()快2倍以上
for idx, (house_lat, house_lon) in enumerate(zip(small_housing_df['latitude'], small_housing_df['longitude'])):
    house_loc = (house_lat, house_lon)
    # 计算当前房屋到所有超市的距离,和你原有的列表推导逻辑完全一致
    all_distance = [geodesic(house_loc, s_loc).km for s_loc in supermarket_locs]
    # 找到最近超市的索引,把结果存在临时列表里,不操作原DataFrame
    min_dis_idx = all_distance.index(min(all_distance))
    match_result.append(supermarket_brands[min_dis_idx])
    print(f"{idx+1} of {total_count}")

# 所有计算完成后,一次性给房屋数据集新增列,全程只做1次DataFrame修改
small_housing_df['closest_store_brand'] = match_result

这个改法和你原有代码的计算结果完全一致,没有额外依赖,只调整了赋值逻辑就能获得数倍性能提升。


方案2:高性能空间计算版(万级数据秒级返回,性能提升100倍以上)

如果你的数据集规模较大(房屋/超市点位过万),纯Python循环的性能还是会遇到瓶颈,推荐用空间索引做最近邻检索,把时间复杂度从O(房屋数*超市数)降到O((房屋数+超市数)*log(超市数)):

import numpy as np
from sklearn.neighbors import BallTree

# 球树计算地理距离需要先把经纬度转成弧度
house_rad = np.deg2rad(small_housing_df[['latitude', 'longitude']].values)
market_rad = np.deg2rad(adjusted_supermarket_df[['lat_wgs', 'long_wgs']].values)

# 构建地理空间球树索引
ball_tree = BallTree(market_rad, metric='haversine')
# 批量查询每个房屋最近的1个超市,返回距离和对应超市的索引
distance, nearest_idx = ball_tree.query(house_rad, k=1)

# 批量匹配超市品牌,一次性赋值
small_housing_df['closest_store_brand'] = adjusted_supermarket_df.iloc[nearest_idx.flatten()]['retailer'].values
# 如需保留最近距离,可直接新增列(乘以地球半径6371得到公里单位)
small_housing_df['nearest_market_dis_km'] = distance.flatten() * 6371

注意:这个方案用哈弗辛公式计算球面距离,和geopy测地线距离的误差通常在0.5%以内,绝大多数业务场景都可以直接使用。如果需要和原有计算精度完全一致,可以替换为geopandas的sjoin_nearest方法,指定测地线距离作为计算指标。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 19:42:22