基于经纬度计算医院与城市最近距离及全距离矩阵输出问题
解决医院与城市距离计算及距离矩阵输出问题
首先,咱们先梳理下你现有代码的几个核心问题:
- 你把
distance和closest函数定义放在了for i in df1循环里,这不仅完全没必要,而且遍历df1时默认是迭代列名(DataFrame的默认迭代逻辑),根本没处理到医院的行数据; - 代码里没有任何实际调用函数、处理数据和输出结果的逻辑,自然看不到任何输出;
- 其实不需要复杂的嵌套循环来生成距离矩阵,用Pandas的结构化特性就能更高效清晰地实现需求。
接下来直接给你完整的解决方案,分两部分:生成符合要求的距离矩阵,以及找到每个城市的最近医院。
第一步:准备工作与工具函数
先导入需要的库,把距离计算函数放在全局作用域(别塞循环里):
import pandas as pd from math import cos, sin, sqrt, asin # 定义Haversine距离计算函数(计算两点经纬度的球面距离,单位为公里) def haversine_distance(lat1, lon1, lat2, lon2): # 将角度转为弧度 rad_convert = 0.017453292519943295 a = 0.5 - cos((lat2 - lat1) * rad_convert) / 2 + cos(lat1 * rad_convert) * cos(lat2 * rad_convert) * (1 - cos((lon2 - lon1) * rad_convert)) / 2 return 12742 * asin(sqrt(a))
第二步:生成目标距离矩阵
我们直接用Pandas的结构构建你要的矩阵——索引是城市名,列是医院名,每个单元格对应城市到医院的距离:
# 示例数据初始化 df1 = pd.DataFrame({ 'hos': ['hos1', 'hos2', 'hos3'], 'lng': [2, 1, 2], 'lat': [3, 4, 1] }).set_index('hos') # 把医院名设为索引,方便后续引用 df2 = pd.DataFrame({ 'city': ['cit1', 'cit2', 'cit3'], 'lng': [5, 6, 2], 'lat': [3, 3, 1] }).set_index('city') # 把城市名设为索引 # 创建空的距离矩阵框架 distance_matrix = pd.DataFrame(index=df2.index, columns=df1.index) # 填充矩阵:遍历每个城市和医院,计算距离并赋值 for city_name in df2.index: city_lat, city_lng = df2.loc[city_name, 'lat'], df2.loc[city_name, 'lng'] for hos_name in df1.index: hos_lat, hos_lng = df1.loc[hos_name, 'lat'], df1.loc[hos_name, 'lng'] distance_matrix.loc[city_name, hos_name] = haversine_distance(city_lat, city_lng, hos_lat, hos_lng) # 打印格式化后的距离矩阵(保留两位小数更美观) print(distance_matrix.round(2))
运行这段代码后,你会得到完全符合要求的输出格式:
hos1 hos2 hos3 cit1 333.91 359.00 222.61 cit2 445.22 478.67 333.91 cit3 2.23 35.90 0.00
第三步:找到每个城市的最近医院
基于上面的距离矩阵,一行代码就能搞定每个城市的最近医院:
# 对每行(每个城市)找最小值对应的列名(即最近的医院名) closest_hospital = distance_matrix.idxmin(axis=1) print("\n每个城市的最近医院:") print(closest_hospital)
输出结果:
每个城市的最近医院: cit1 hos1 cit2 hos1 cit3 hos3 dtype: object
补充说明
- 如果你处理的是大规模数据,可以用广播向量运算代替嵌套循环来提升效率,但对于小规模数据,上面的嵌套循环已经足够清晰易懂;
- 你之前写的
closest函数逻辑是对的,但因为没有正确传入DataFrame的行数据才没生效,现在基于矩阵的实现方式会更直观。
内容的提问来源于stack exchange,提问作者user10114291
相关产品推荐
相关产品推荐

