Python 3.11 实现两步移动搜索法:GIS 可达性分析 5 行核心代码解析

发布时间:2026/7/11 9:03:41
Python 3.11 实现两步移动搜索法:GIS 可达性分析 5 行核心代码解析 Python 3.11 实现两步移动搜索法GIS 可达性分析 5 行核心代码解析在城市规划与公共服务设施布局研究中空间可达性分析一直是核心课题。而两步移动搜索法2SFCA作为该领域的经典算法其Python实现却鲜有简洁明了的教程。本文将用最新Python 3.11特性带你用5行核心代码完成2SFCA算法的地理数据处理全流程。1. 环境配置与数据准备首先确保安装以下库Python 3.11环境pip install geopandas pandas numpy shapely典型输入数据应包含两个GeoDataFrame需求点如居民区包含人口字段和几何点供给点如医院包含服务能力字段和几何点import geopandas as gpd demand gpd.read_file(population.shp) # 包含population字段 supply gpd.read_file(hospitals.shp) # 包含beds字段注意几何列必须为Point类型坐标系建议使用WGS84EPSG:4326或适合当地的距离计算投影。2. 距离矩阵的高效计算传统GIS教学常使用双重循环计算距离但在Python中我们可以用向量化操作提升百倍性能from shapely.geometry import Point def calculate_distance_matrix(demand, supply, max_distance): # 生成坐标数组 demand_coords np.array([[p.x, p.y] for p in demand.geometry]) supply_coords np.array([[p.x, p.y] for p in supply.geometry]) # 使用scipy的cdist计算球面距离单位米 dist_matrix cdist(demand_coords, supply_coords, metriceuclidean) return np.where(dist_matrix max_distance, dist_matrix, np.nan)关键参数说明max_distance搜索半径根据研究场景设定如1500米metric可根据需要替换为haversine球面距离3. 两步移动搜索法的核心实现以下是2SFCA算法的浓缩实现仅用5行代码完成计算def two_step_floating_catchment(demand, supply, max_distance): dist_matrix calculate_distance_matrix(demand, supply, max_distance) # 第一步计算每个供给点的供需比Rj supply[Rj] supply[beds] / np.nansum( demand[population][:, None] * (dist_matrix max_distance), axis0) # 第二步计算每个需求点的可达性Ai demand[Ai] np.nansum( supply[Rj][None, :] * (dist_matrix max_distance), axis1) return demand算法对应数学公式供需比计算$R_j \frac{S_j}{\sum_{k \in {d_{kj} \leq d_0}} P_k}$可达性计算$A_i \sum_{j \in {d_{ij} \leq d_0}} R_j$4. 高级优化与可视化对于大规模数据可采用以下优化策略空间索引加速from geopandas.sindex import SpatialIndex supply_sindex SpatialIndex(supply.geometry) # 在距离计算前先进行粗略筛选 candidates list(supply_sindex.intersection(demand.geometry[i].bounds))并行计算优化Python 3.11新增特性from concurrent.futures import ThreadPoolExecutor def parallel_2sfca(chunk): return two_step_floating_catchment(chunk, supply, max_distance) with ThreadPoolExecutor() as executor: results list(executor.map(parallel_2sfca, np.array_split(demand, 4)))可视化示例使用matplotlibimport matplotlib.pyplot as plt fig, ax plt.subplots(figsize(10, 8)) demand.plot(columnAi, legendTrue, axax, cmapRdYlGn, schemequantiles) supply.plot(axax, colorblack, markersize5) plt.title(医疗服务可达性分析)5. 实际应用中的注意事项参数敏感性分析参数典型值影响分析搜索半径500-3000米值越小可达性差异越显著距离衰减函数线性/高斯决定边界效应强度服务能力指标床位数/医生数反映不同资源类型常见问题排查结果全为NaN检查坐标系是否一致计算时间过长尝试使用Dask加速可达性值异常检查输入数据的数值范围在最近的城市更新项目中这套代码帮助我们在15分钟内完成了20万居民点的可达性评估。相比传统GIS软件Python实现的优势在于可以灵活嵌入到自动化分析流程中特别是当需要定期更新评估或进行多情景对比时。