如何用Python快速计算全国城市到杭州的球面距离(附完整代码)

发布时间:2026/7/12 16:38:57

如何用Python快速计算全国城市到杭州的球面距离(附完整代码) 用Python实现全国城市到杭州的球面距离计算与可视化实战在数据分析与地理信息系统GIS开发中计算两个地理位置之间的球面距离是一项基础但关键的任务。不同于简单的直线距离球面距离考虑了地球的曲率能够更准确地反映实际地表距离。本文将手把手教你如何用Python从零开始构建一个完整的解决方案包括城市坐标获取、距离计算和结果可视化三大核心模块。1. 环境准备与数据获取在开始编码之前我们需要搭建合适的Python环境并准备必要的数据。计算球面距离主要依赖地理坐标数据这里我们有两种获取方式使用现有API实时查询或导入本地预存数据集。首先安装必要的Python库pip install geopy pandas requests matplotlib对于城市坐标数据可以考虑以下几种来源高德/百度地图API通过它们的开放平台获取精确的城市经纬度GeoNames数据库提供全球城市的地理信息本地CSV文件如原始资料中提到的社科数据集这里我们演示如何从本地CSV文件加载数据import pandas as pd # 假设数据文件为cities_data.csv data pd.read_csv(cities_data.csv, encodinggbk) # 中文编码常用gbk print(data.head())如果选择使用API获取实时数据可以参考以下代码框架import requests def get_city_coordinates(city_name, api_key): base_url https://restapi.amap.com/v3/geocode/geo params { key: api_key, address: city_name } response requests.get(base_url, paramsparams) if response.status_code 200: result response.json() if result[status] 1 and result[geocodes]: location result[geocodes][0][location] return tuple(map(float, location.split(,))) return None2. 球面距离计算的核心算法计算球面距离主要有两种方法使用现成的geopy库或手动实现Haversine公式。我们先介绍更简单的geopy方法。2.1 使用geopy库计算距离geopy提供了便捷的距离计算功能支持多种地球模型和距离单位from geopy.distance import geodesic # 杭州的经纬度坐标 hangzhou_coord (30.2741, 120.1551) def calculate_distance_geopy(city_coord): return geodesic(city_coord, hangzhou_coord).km # 示例计算北京到杭州的距离 beijing_coord (39.9042, 116.4074) distance calculate_distance_geopy(beijing_coord) print(f北京到杭州的距离{distance:.2f}公里)2.2 手动实现Haversine公式对于需要更高性能或自定义计算逻辑的场景可以手动实现Haversine公式import math def haversine(lon1, lat1, lon2, lat2): # 将十进制度数转化为弧度 lon1, lat1, lon2, lat2 map(math.radians, [lon1, lat1, lon2, lat2]) # Haversine公式 dlon lon2 - lon1 dlat lat2 - lat1 a math.sin(dlat/2)**2 math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2 c 2 * math.asin(math.sqrt(a)) r 6371 # 地球平均半径单位为公里 return c * r # 示例使用 distance haversine(116.4074, 39.9042, 120.1551, 30.2741) print(f使用Haversine公式计算的距离{distance:.2f}公里)两种方法的对比方法优点缺点精度geopy使用简单支持多种地球模型依赖外部库性能稍低高Haversine性能高不依赖外部库需要手动实现高3. 批量处理与数据分析有了单个城市的计算能力我们需要扩展到全国城市数据集。这里展示如何高效处理大量城市数据。首先确保数据格式统一# 数据清洗示例 def clean_data(df): # 处理缺失值 df df.dropna(subset[lng, lat]) # 确保经纬度在合理范围内 df df[(df[lng].between(-180, 180)) (df[lat].between(-90, 90))] return df cleaned_data clean_data(data)然后批量计算所有城市到杭州的距离def batch_calculate_distances(df, hangzhou_coord): results [] for _, row in df.iterrows(): city_coord (row[lat], row[lng]) try: distance geodesic(city_coord, hangzhou_coord).km results.append({ city: row[city], province: row[province], distance_km: distance }) except ValueError as e: print(f计算{row[city]}距离时出错{e}) return pd.DataFrame(results) distances_df batch_calculate_distances(cleaned_data, hangzhou_coord)数据分析示例 - 找出距离杭州最近和最远的10个城市# 按距离排序 sorted_distances distances_df.sort_values(distance_km) # 最近10个城市 print(距离杭州最近的10个城市) print(sorted_distances.head(10)) # 最远10个城市 print(\n距离杭州最远的10个城市) print(sorted_distances.tail(10))4. 结果可视化与地图展示数据可视化是GIS分析的重要环节我们使用Matplotlib和Basemap工具包来创建专业的地图展示。首先安装必要的可视化库pip install basemap然后创建距离可视化地图import matplotlib.pyplot as plt from mpl_toolkits.basemap import Basemap import numpy as np plt.figure(figsize(12, 10)) # 创建中国地图投影 m Basemap(llcrnrlon73, llcrnrlat15, urcrnrlon135, urcrnrlat55, projectionlcc, lat_133, lat_245, lon_0100) m.drawcoastlines() m.drawcountries(linewidth1.5) m.drawparallels(np.arange(0, 81, 10), labels[1,0,0,0]) m.drawmeridians(np.arange(0, 361, 15), labels[0,0,0,1]) # 绘制城市点 for _, row in distances_df.iterrows(): x, y m(row[lng], row[lat]) distance row[distance_km] # 根据距离设置点的大小和颜色 size max(5, 30 - distance/500) color plt.cm.rainbow(distance/3000) # 假设最大距离3000km m.plot(x, y, o, markersizesize, colorcolor) # 标记杭州位置 hz_x, hz_y m(120.1551, 30.2741) m.plot(hz_x, hz_y, r*, markersize15, labelHangzhou) # 添加颜色条 sm plt.cm.ScalarMappable(cmaprainbow, normplt.Normalize(vmin0, vmax3000)) sm._A [] plt.colorbar(sm, labelDistance to Hangzhou (km)) plt.title(Distance from Chinese Cities to Hangzhou) plt.legend() plt.show()更高级的可视化选项包括热力图展示距离密度分布3D地图使用mpl_toolkits.mplot3d创建立体效果交互式地图结合Folium库创建可缩放的地图import folium # 创建基础地图 m folium.Map(location[35, 105], zoom_start5) # 添加城市标记 for _, row in distances_df.iterrows(): folium.CircleMarker( location[row[lat], row[lng]], radiusrow[distance_km]/500, # 按距离调整大小 colorblue, fillTrue, fill_colorblue, popupf{row[city]}: {row[distance_km]:.1f}km ).add_to(m) # 标记杭州 folium.Marker( [30.2741, 120.1551], popupHangzhou, iconfolium.Icon(colorred) ).add_to(m) m.save(china_distance_map.html)5. 性能优化与扩展应用当处理大量城市数据时计算性能变得重要。以下是几种优化策略5.1 向量化计算使用NumPy进行向量化运算可以大幅提升性能import numpy as np def vectorized_haversine(lats, lons, hangzhou_lat, hangzhou_lon): # 转换为弧度 lats np.radians(lats) lons np.radians(lons) hangzhou_lat np.radians(hangzhou_lat) hangzhou_lon np.radians(hangzhou_lon) # 计算差值 dlat hangzhou_lat - lats dlon hangzhou_lon - lons # Haversine公式 a np.sin(dlat/2)**2 np.cos(lats) * np.cos(hangzhou_lat) * np.sin(dlon/2)**2 c 2 * np.arcsin(np.sqrt(a)) r 6371 # 地球半径(km) return c * r # 示例使用 lats cleaned_data[lat].values lons cleaned_data[lng].values distances vectorized_haversine(lats, lons, 30.2741, 120.1551)5.2 并行计算对于超大规模数据集可以使用multiprocessing进行并行处理from multiprocessing import Pool def parallel_distance_calculation(df, hangzhou_coord, processes4): # 将DataFrame分割为多个部分 chunks np.array_split(df, processes) # 创建计算函数 def calculate_chunk(chunk): return chunk.apply(lambda row: geodesic( (row[lat], row[lng]), hangzhou_coord ).km, axis1) # 并行计算 with Pool(processes) as pool: results pool.map(calculate_chunk, chunks) # 合并结果 return pd.concat(results) # 使用示例 distances parallel_distance_calculation(cleaned_data, hangzhou_coord)5.3 实际应用扩展这套计算方法可以扩展到多种实际应用场景物流路径优化计算多个配送中心到各城市的最优路径商业选址分析评估潜在店址与目标客户群的距离城市规划分析城市群之间的空间关系学术研究作为地理因素的工具变量例如创建一个简单的商业选址评分函数def location_score(distance, population, gdp): 基于距离、人口和GDP计算位置得分 distance: 到杭州的距离(km) population: 城市人口(万) gdp: 城市GDP(亿元) distance_factor 1 / (1 distance/500) # 距离衰减因子 return distance_factor * population * gdp # 应用评分函数 distances_df[score] distances_df.apply( lambda row: location_score( row[distance_km], row.get(population, 100), # 假设有这些字段 row.get(gdp, 100) ), axis1 )

相关新闻