
























本章将带你全面了解 GeoPandas 的背景、定位、核心特性以及应用场景,并通过一个完整的快速体验示例,让你在最短时间内感受 GeoPandas 的强大能力。
GeoPandas 是一个开源的 Python 库,旨在让 地理空间数据 在 Python 中的处理变得更加简单高效。它建立在 pandas 的基础之上,通过扩展 DataFrame 和 Series,使得用户可以像操作普通表格数据一样操作矢量地理空间数据。
GeoPandas 最早由 Kelsey Jordahl 于 2013 年创建,目的是填补 Python 数据科学生态中地理空间数据处理的空白。传统上,处理地理空间数据需要使用专业的 GIS 软件(如 ArcGIS、QGIS)或底层库(如 OGR/GDAL),学习曲线陡峭。GeoPandas 让熟悉 pandas 的数据科学家能够零障碍地处理空间数据。
| 时间 | 里程碑 |
|---|---|
| 2013 年 | Kelsey Jordahl 创建 GeoPandas 项目 |
| 2014 年 | 发布 v0.1,支持基本的空间数据读写和操作 |
| 2017 年 | 社区贡献者大幅增加,功能日趋完善 |
| 2020 年 | v0.8 发布,引入新的空间索引引擎 |
| 2022 年 | v0.12 发布,开始向 Shapely 2.0 过渡 |
| 2023 年 | v0.14 发布,全面拥抱 Shapely 2.0,性能大幅提升 |
| 2024 年 | v1.0 发布,标志着 API 稳定性的重大里程碑 |
| 2025 年 | v1.1 发布,进一步优化性能与功能 |
GeoPandas 托管在 GitHub 上(geopandas/geopandas),采用 BSD 3-Clause 开源协议。
社区活跃在多个平台:
geopandas 下有大量问答如果说 PostGIS 是 PostgreSQL 的地理空间扩展,那么 GeoPandas 就是 pandas 的地理空间扩展。
PostgreSQL + PostGIS = 空间数据库
pandas + GeoPandas = 空间数据分析框架
这种类比帮助我们理解 GeoPandas 的核心定位:
| 特性 | PostGIS | GeoPandas |
|---|---|---|
| 基础平台 | PostgreSQL 数据库 | pandas DataFrame |
| 空间类型 | geometry/geography 列 | GeoSeries (geometry 列) |
| 空间函数 | ST_Buffer, ST_Intersects 等 | buffer(), intersects() 等 |
| 空间索引 | GiST/SP-GiST | STRtree |
| 坐标参考系 | SRID | CRS (pyproj) |
| 查询语言 | SQL | Python/pandas API |
需要注意的是,GeoPandas 并非万能的:
GeoPandas 提供了丰富的地理空间数据处理能力,以下是其核心特性的概览:
import geopandas as gpd
# 读取 Shapefile
gdf = gpd.read_file("cities.shp")
# 读取 GeoJSON
gdf = gpd.read_file("boundaries.geojson")
# 读取 GeoPackage
gdf = gpd.read_file("data.gpkg", layer="buildings")
支持的矢量格式包括但不限于:
| 格式 | 读取 | 写入 | 说明 |
|---|---|---|---|
| Shapefile (.shp) | ✅ | ✅ | 经典格式,广泛使用 |
| GeoJSON (.geojson) | ✅ | ✅ | Web 友好的 JSON 格式 |
| GeoPackage (.gpkg) | ✅ | ✅ | 现代替代 Shapefile |
| FlatGeobuf (.fgb) | ✅ | ✅ | 高性能流式格式 |
| Parquet (.parquet) | ✅ | ✅ | 列式存储,高效压缩 |
| Feather (.feather) | ✅ | ✅ | 快速序列化格式 |
| KML (.kml) | ✅ | ✅ | Google Earth 格式 |
| CSV (含 WKT) | ✅ | ✅ | 文本格式 |
GeoPandas 内置了丰富的空间分析功能:
# 缓冲区分析
buffered = gdf.buffer(distance=1000) # 1000 米缓冲区
# 空间叠加
result = gpd.overlay(gdf1, gdf2, how='intersection')
# 空间连接
joined = gpd.sjoin(points, polygons, predicate='within')
# 距离计算
distances = gdf1.distance(gdf2)
# 面积计算
areas = gdf.area
# 质心计算
centroids = gdf.centroid
# 查看 CRS
print(gdf.crs) # EPSG:4326
# 投影转换
gdf_projected = gdf.to_crs(epsg=3857)
# 自定义 CRS
from pyproj import CRS
custom_crs = CRS.from_proj4("+proj=aea +lat_1=25 +lat_2=47 +lon_0=105")
gdf_custom = gdf.to_crs(custom_crs)
import matplotlib.pyplot as plt
# 基础绘图
gdf.plot(column='population', cmap='YlOrRd', legend=True)
plt.title("人口分布图")
plt.show()
# 交互式地图
m = gdf.explore(column='population', cmap='YlOrRd')
m.save("interactive_map.html")
# 空间索引自动创建
sindex = gdf.sindex
# 查询某个范围内的要素
bbox = (116.0, 39.0, 117.0, 40.0)
candidates = list(sindex.query(bbox))
| 对比维度 | GeoPandas | ArcPy |
|---|---|---|
| 授权费用 | 免费开源 | 需要 ArcGIS 许可证(昂贵) |
| 安装 | pip/conda 轻松安装 | 必须安装 ArcGIS Desktop/Pro |
| 数据模型 | DataFrame 风格 | 游标(Cursor)风格 |
| 批量处理 | 向量化操作,高效 | 逐行处理,较慢 |
| 可扩展性 | 可与任意 Python 库配合 | 受 ArcGIS 环境限制 |
| 社区支持 | 开源社区活跃 | 官方支持 + 用户社区 |
| 功能丰富度 | 聚焦矢量分析 | 全面的 GIS 功能 |
| 栅格处理 | 不直接支持 | 完整支持 |
适用场景:
| 对比维度 | GeoPandas | QGIS Processing |
|---|---|---|
| 使用方式 | 纯代码 | GUI + Python 脚本 |
| 学习曲线 | 需要编程基础 | 可视化操作更直观 |
| 自动化 | 天然支持批处理 | 通过模型构建器或 PyQGIS |
| 数据规模 | 内存限制 | 同样受内存限制 |
| 可复现性 | 代码即文档 | 需要额外记录步骤 |
| 费用 | 免费 | 免费 |
| 对比维度 | GeoPandas | PostGIS |
|---|---|---|
| 运行环境 | 内存中 | 数据库服务器 |
| 数据规模 | 适合中小规模 | 可处理海量数据 |
| 并发访问 | 单用户 | 多用户并发 |
| 查询语言 | Python API | SQL |
| 空间函数 | 100+ | 300+ |
| 事务支持 | 无 | ACID 事务 |
| 适用场景 | 探索性分析 | 生产环境数据管理 |
| 对比维度 | GeoPandas (Python) | sf (R) |
|---|---|---|
| 生态系统 | Python 数据科学 | R 统计分析 |
| 底层引擎 | Shapely + pyproj | GEOS + PROJ |
| 数据模型 | GeoDataFrame | sf data.frame |
| 可视化 | matplotlib + folium | ggplot2 + tmap |
| 机器学习集成 | scikit-learn, PyTorch | caret, tidymodels |
| 性能 | 向量化操作优异 | 向量化操作优异 |
| 语法风格 | 面向对象 | tidyverse 管道 |
GeoPandas 并非独立工作,而是构建在一系列优秀的开源库之上:
GeoPandas
├── pandas (>= 2.2) # 表格数据处理
│ └── numpy (>= 2.0) # 数值计算
├── shapely (>= 2.1) # 几何对象与操作
│ └── GEOS # C++ 几何引擎
├── pyproj (>= 3.7) # 坐标参考系与投影
│ └── PROJ # C 投影库
├── pyogrio (>= 0.8) # 空间数据I/O
│ └── GDAL/OGR # C/C++ 空间数据引擎
└── packaging # 版本解析
| 库 | 版本要求 | 用途 |
|---|---|---|
| matplotlib | >= 3.9 | 静态地图绘制 |
| folium | - | 交互式 Web 地图 |
| mapclassify | >= 2.7.3 | 数据分类方案(自然断裂点、等间距等) |
| xyzservices | - | 瓦片地图服务 |
| geopy | - | 地理编码(地址转坐标) |
| psycopg | - | PostgreSQL 连接(用于 PostGIS) |
| SQLAlchemy | >= 2.0 | 数据库 ORM |
| GeoAlchemy2 | - | SQLAlchemy 的地理空间扩展 |
| pyarrow | >= 15.0 | Parquet/Feather 格式支持 |
| scipy | - | 科学计算(Voronoi 图等) |
| pointpats | - | 点模式分析 |
┌─────────────────────────────┐
│ GeoPandas 生态系统 │
└─────────────────────────────┘
│
┌───────────────────────┼───────────────────────┐
│ │ │
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
│ 数据 I/O │ │ 空间分析 │ │ 可视化 │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘
│ │ │
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
│ pyogrio │ │ shapely │ │ matplotlib│
│ pyarrow │ │ scipy │ │ folium │
│ psycopg │ │ pointpats │ │ contextily│
└───────────┘ └───────────┘ └───────────┘
GeoPandas 在众多领域都有广泛应用:
import geopandas as gpd
# 读取城市用地规划数据
land_use = gpd.read_file("land_use.shp")
# 计算各类用地面积
land_use['面积_平方公里'] = land_use.to_crs(epsg=32650).area / 1e6
# 按用地类型统计
summary = land_use.groupby('用地类型')['面积_平方公里'].sum()
print(summary)
典型任务:
# 读取监测站点和行政区划数据
stations = gpd.read_file("monitoring_stations.geojson")
districts = gpd.read_file("districts.geojson")
# 空间连接:将站点关联到所在区域
joined = gpd.sjoin(stations, districts, predicate='within')
# 按区域计算平均污染指数
avg_pollution = joined.groupby('区域名称')['PM25'].mean()
典型任务:
# 读取道路网络数据
roads = gpd.read_file("road_network.shp")
# 计算道路长度
roads['长度_km'] = roads.to_crs(epsg=32650).length / 1000
# 按道路等级统计里程
mileage = roads.groupby('道路等级')['长度_km'].sum()
# 创建道路缓冲区(模拟噪音影响范围)
noise_zones = roads.to_crs(epsg=32650).buffer(50) # 50米缓冲区
# 读取房产和配套设施数据
properties = gpd.read_file("properties.geojson")
schools = gpd.read_file("schools.geojson")
# 计算每个房产到最近学校的距离
properties_proj = properties.to_crs(epsg=32650)
schools_proj = schools.to_crs(epsg=32650)
# 计算最近学校距离
from shapely.ops import nearest_points
properties_proj['到最近学校距离'] = properties_proj.geometry.apply(
lambda x: schools_proj.distance(x).min()
)
| 领域 | 应用示例 |
|---|---|
| 公共卫生 | 疫情空间传播分析、医疗资源分布 |
| 农业 | 农田边界管理、作物分布统计 |
| 电力能源 | 输电线路管理、风电场选址 |
| 物流配送 | 配送范围划分、仓库选址优化 |
| 保险 | 灾害风险区域评估、保单空间分析 |
| 考古学 | 遗址分布分析、文物保护区管理 |
下面通过一个完整的示例,体验 GeoPandas 的核心工作流程。
import geopandas as gpd
import matplotlib.pyplot as plt
# ========================================
# 步骤 1:读取数据
# ========================================
# 使用 GeoPandas 内置的世界各国数据集
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
# 查看数据概览
print("数据形状:", world.shape)
print("\n列名:", world.columns.tolist())
print("\n前5行数据:")
print(world.head())
print("\n坐标参考系:", world.crs)
# ========================================
# 步骤 2:数据探索
# ========================================
# 查看数据类型
print("\n数据类型:")
print(world.dtypes)
# 基本统计
print("\n人口统计:")
print(world['pop_est'].describe())
# 按大洲分组统计
continent_stats = world.groupby('continent').agg({
'pop_est': ['sum', 'mean', 'count'],
'gdp_md_est': 'sum'
}).round(0)
print("\n大洲统计:")
print(continent_stats)
# ========================================
# 步骤 3:空间分析
# ========================================
# 计算各国面积(使用等面积投影)
world_aea = world.to_crs('+proj=aea +lat_1=20 +lat_2=60 +lon_0=0')
world['area_km2'] = world_aea.area / 1e6 # 转换为平方公里
# 计算人口密度
world['pop_density'] = world['pop_est'] / world['area_km2']
# 找出人口密度最高的 10 个国家
top10_density = world.nlargest(10, 'pop_density')[['name', 'pop_density', 'pop_est']]
print("\n人口密度 TOP 10:")
print(top10_density)
# ========================================
# 步骤 4:空间操作
# ========================================
# 获取各国质心
world['centroid'] = world.centroid
# 计算中国的邻国
china = world[world['name'] == 'China']
neighbors = world[world.touches(china.unary_union)]
print(f"\n中国的邻国 ({len(neighbors)} 个):")
print(neighbors['name'].tolist())
# ========================================
# 步骤 5:可视化
# ========================================
fig, axes = plt.subplots(2, 2, figsize=(20, 16))
# 子图1:世界政区图
world.plot(ax=axes[0, 0], color='lightblue', edgecolor='gray')
axes[0, 0].set_title('世界政区图', fontsize=14)
axes[0, 0].set_axis_off()
# 子图2:人口分布图
world.plot(column='pop_est', ax=axes[0, 1], legend=True,
legend_kwds={'label': '人口数量', 'shrink': 0.6},
cmap='YlOrRd', missing_kwds={'color': 'lightgrey'})
axes[0, 1].set_title('世界人口分布', fontsize=14)
axes[0, 1].set_axis_off()
# 子图3:人均GDP
world.plot(column='gdp_md_est', ax=axes[1, 0], legend=True,
legend_kwds={'label': 'GDP (百万美元)', 'shrink': 0.6},
cmap='Greens', missing_kwds={'color': 'lightgrey'})
axes[1, 0].set_title('世界 GDP 分布', fontsize=14)
axes[1, 0].set_axis_off()
# 子图4:人口密度
world.plot(column='pop_density', ax=axes[1, 1], legend=True,
legend_kwds={'label': '人口密度 (人/km²)', 'shrink': 0.6},
cmap='OrRd', scheme='quantiles',
missing_kwds={'color': 'lightgrey'})
axes[1, 1].set_title('世界人口密度分布', fontsize=14)
axes[1, 1].set_axis_off()
plt.tight_layout()
plt.savefig('world_analysis.png', dpi=150, bbox_inches='tight')
plt.show()
# ========================================
# 步骤 6:数据导出
# ========================================
# 导出为 GeoJSON
world.to_file("world_with_density.geojson", driver="GeoJSON")
# 导出为 GeoPackage
world.to_file("world_analysis.gpkg", layer="countries", driver="GPKG")
print("\n分析完成!数据已导出。")
运行上述代码后,你将得到:
这个简单的示例展示了 GeoPandas 的核心工作流程:
读取数据 → 数据探索 → 空间分析 → 空间操作 → 可视化 → 数据导出
为了系统地掌握 GeoPandas,建议按照以下路线学习:
第1章:概述与入门 ← 你在这里
│
第2章:安装与环境配置
│
第3章:核心架构与数据模型
│
第4章:GeoDataFrame 基础操作
│
第5章:GeoSeries 与几何对象
目标:掌握 GeoPandas 的基本概念、数据结构和基础操作。
在开始学习 GeoPandas 之前,建议具备以下知识:
| 知识领域 | 要求程度 | 推荐资源 |
|---|---|---|
| Python 基础 | 必须 | Python 官方教程 |
| pandas | 强烈建议 | pandas 官方文档 |
| GIS 基础概念 | 建议了解 | 地理信息系统导论 |
| matplotlib | 建议了解 | matplotlib 官方教程 |
| numpy | 了解即可 | numpy 快速入门 |
本章介绍了以下内容:
| 主题 | 要点 |
|---|---|
| GeoPandas 简介 | 开源 Python 地理空间数据处理库,2013 年创建 |
| 定位与价值 | pandas 的地理空间扩展,Python 中的 PostGIS |
| 核心特性 | 矢量数据处理、空间分析、CRS、可视化、IO |
| 工具对比 | 与 ArcPy、QGIS、PostGIS、R sf 各有优劣 |
| 技术栈 | 建立在 pandas、shapely、pyproj、pyogrio 之上 |
| 应用场景 | 城市规划、环境监测、交通分析等多个领域 |
| 快速体验 | 完整的世界各国人口数据分析示例 |
| 学习路线 | 从基础到进阶的系统学习路径 |
下一章预告:第 2 章将详细介绍 GeoPandas 的安装与环境配置,确保你的开发环境准备就绪。
📚 参考资料
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。