基于Haversine公式生成500×500距离矩阵并匹配最近仓库
没问题,我帮你搞定这个基于Haversine公式的距离计算和仓库匹配需求!下面是完整的可运行代码和步骤说明,直接套用你的coordinate.csv就能用:
实现步骤与代码
1. 依赖库准备
先确保你装了pandas和numpy,没装的话先跑这条命令:
pip install pandas numpy
2. 读取坐标数据
假设你的coordinate.csv是这种结构(对应你提供的10条示例数据格式):
| type | name | latitude | longitude |
|---|---|---|---|
| warehouse | WarehouseA | 39.9042 | 116.4074 |
| customer | Customer1 | 31.2304 | 121.4737 |
| ... | ... | ... | ... |
用Pandas读取数据:
import pandas as pd import numpy as np # 读取坐标文件 df = pd.read_csv('coordinate.csv')
3. 实现Haversine公式
这个公式专门用来计算地球表面两点的球面距离,精度很高,适合地理坐标的距离计算:
def haversine(lat1, lon1, lat2, lon2): # 把角度转成弧度(numpy三角函数默认用弧度计算) lat1, lon1, lat2, lon2 = map(np.radians, [lat1, lon1, lat2, lon2]) # Haversine核心计算逻辑 dlat = lat2 - lat1 dlon = lon2 - lon1 a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2 c = 2 * np.arcsin(np.sqrt(a)) # 地球平均半径(单位:公里,要算英里的话换成3956) r = 6371 return c * r
4. 生成500×500距离矩阵
用numpy的广播机制批量计算,比循环效率高太多,适合处理500个地点的规模:
# 提取所有地点的经纬度数组 latitudes = df['latitude'].values longitudes = df['longitude'].values # 初始化距离矩阵 distance_matrix = np.zeros((len(df), len(df))) for i in range(len(df)): # 一次性计算当前地点到所有其他地点的距离 distance_matrix[i] = haversine(latitudes[i], longitudes[i], latitudes, longitudes) # 转成带地点名称的DataFrame,方便查看和保存 distance_matrix_df = pd.DataFrame( distance_matrix, index=df['name'], columns=df['name'] ) # 可选:把距离矩阵保存到本地文件 distance_matrix_df.to_csv('distance_matrix.csv')
5. 为客户匹配最近仓库
先拆分仓库和客户数据,再逐个计算客户到所有仓库的距离,取最小值对应的仓库:
# 分离仓库和客户数据集 warehouses = df[df['type'] == 'warehouse'] customers = df[df['type'] == 'customer'] # 初始化结果列表 match_results = [] for _, customer in customers.iterrows(): # 计算当前客户到所有仓库的距离 distances = haversine( customer['latitude'], customer['longitude'], warehouses['latitude'].values, warehouses['longitude'].values ) # 找到距离最小的仓库索引 min_idx = np.argmin(distances) # 提取最近仓库的名称和距离值 nearest_warehouse = warehouses.iloc[min_idx]['name'] min_distance = round(distances[min_idx], 2) # 保留两位小数 match_results.append({ 'customer_name': customer['name'], 'nearest_warehouse': nearest_warehouse, 'distance_km': min_distance }) # 转成DataFrame格式的匹配结果 match_results_df = pd.DataFrame(match_results) # 可选:保存匹配结果到本地文件 match_results_df.to_csv('customer_warehouse_matches.csv', index=False)
6. 查看结果
运行完代码后,你可以直接打印查看输出:
# 查看距离矩阵的前5行5列 print("距离矩阵(前5×5预览):") print(distance_matrix_df.head()) # 查看客户-仓库匹配结果 print("\n客户-仓库匹配结果:") print(match_results_df.head())
要是你的coordinate.csv字段名和示例不一样,稍微调整代码里的列名就行,比如把type换成category之类的。
内容的提问来源于stack exchange,提问作者belle
相关产品推荐
相关产品推荐

