Python 实现两步移动搜索法基于 ArcPy 与 Pandas 的公共服务可达性计算在城市规划与地理信息科学领域公共服务设施的可达性分析是评估资源分配公平性的重要工具。两步移动搜索法2SFCA作为经典的空间可达性计算方法能够量化居民获取公共服务的便利程度。本文将手把手带您用Python实现完整的2SFCA分析流程结合ArcPy处理空间数据与Pandas进行高效计算最终生成可直接用于决策的可视化结果。1. 环境准备与数据预处理1.1 工具库配置实现2SFCA需要以下Python库支持import arcpy import pandas as pd import numpy as np from scipy.spatial import cKDTree import matplotlib.pyplot as plt关键工具说明arcpy处理空间数据核心工具需ArcGIS许可证pandas表格数据处理引擎cKDTree高效计算空间距离矩阵matplotlib结果可视化提示若无法使用ArcPy可用GeoPandas替代部分功能但会损失部分ArcGIS专属工具1.2 数据格式标准化典型输入数据应包含两个要素类数据类型必需字段说明需求点ID, Population, Geometry居民点/人口统计区供给点ID, Capacity, Geometry医院/学校等设施使用ArcPy进行数据检查def validate_data(input_fc): fields [f.name for f in arcpy.ListFields(input_fc)] assert SHAPE in fields, 缺少几何字段 if Population not in fields and Capacity not in fields: raise ValueError(缺失人口或容量字段)2. 核心算法实现2.1 距离矩阵计算采用空间索引加速计算比传统循环效率提升50倍以上def create_distance_matrix(origins, destinations, max_dist): 构建稀疏距离矩阵 orig_coords np.array([(pt.X, pt.Y) for pt in origins]) dest_coords np.array([(pt.X, pt.Y) for pt in destinations]) tree cKDTree(dest_coords) dists, indices tree.query( orig_coords, klen(dest_coords), distance_upper_boundmax_dist ) return dists, indices参数优化建议城市尺度搜索半径建议1-5km区域尺度建议10-30km医疗设施建议使用分级半径急诊15km专科30km2.2 两步搜索实现完整算法流程分四个阶段数据加载将要素类转为Pandas DataFrame第一步搜索计算每个供给点的服务人口第二步搜索汇总需求点可达资源结果标准化按人口加权处理def calculate_2sfca(demand_fc, supply_fc, threshold): # 转换为DataFrame demand_df featureclass_to_dataframe(demand_fc) supply_df featureclass_to_dataframe(supply_fc) # 第一步供给点搜索 supply_df[Rj] supply_df[Capacity] / demand_in_range( demand_df, supply_df, threshold ) # 第二步需求点搜索 demand_df[Ai] supply_in_range( supply_df, demand_df, threshold ) return demand_df3. 可视化与结果分析3.1 热力图生成使用matplotlib绘制分级色彩图def plot_accessibility(result_df): fig, ax plt.subplots(figsize(12, 8)) sc ax.scatter( result_df.geometry.x, result_df.geometry.y, cresult_df.Ai, cmapYlOrRd, s50, alpha0.6 ) plt.colorbar(sc, label可达性指数) plt.title(公共服务设施可达性分布)3.2 统计指标计算关键评估指标指标公式解读基尼系数$\frac{\sum\sumA_i-A_j变异系数$\sigma/\mu$区域差异度首位比最高值/次高值资源集中度实现代码def calculate_equity_metrics(access_series): gini 0.5 * np.mean(np.abs(np.subtract.outer( access_series, access_series ))) / np.mean(access_series) cv np.std(access_series) / np.mean(access_series) return {Gini: gini, CV: cv}4. 性能优化技巧4.1 并行计算加速对于百万级数据点采用Dask实现分布式计算import dask.dataframe as dd def parallel_2sfca(demand_df, supply_df): dask_demand dd.from_pandas(demand_df, npartitions4) results dask_demand.map_partitions( calculate_partition, supply_dfsupply_df, meta(Ai, float64) ) return results.compute()4.2 内存管理处理大型数据集时的优化策略分块处理将研究区域划分为网格单元稀疏矩阵只存储阈值范围内的距离关系数据压缩使用category类型存储文本字段# 内存优化示例 demand_df[Region] demand_df[Region].astype(category) supply_df[Type] supply_df[Type].astype(category)5. 实际应用案例以某三甲医院选址分析为例演示完整工作流数据准备居民点街道人口统计数据供给点现有医院床位数量参数设置config { search_radius: 15000, # 15公里服务半径 capacity_field: Beds, population_field: Pop2023 }结果解读发现西北城区存在明显服务盲区基尼系数0.42显示资源分配不均新院区选址建议优先考虑低值区注意实际应用中需考虑交通网络阻抗而非直线距离