Fiona读取地理数据?与GeoPandas啥区别?
很多同学在做 Python GIS 数据处理时会搜索“Fiona读取地理数据?与GeoPandas啥区别?”,因为两者都能打开 Shapefile、GeoPackage、GeoJSON 等矢量数据,但写法、返回对象和适用场景并不一样。简单说:Fiona 更像“底层矢量数据读写接口”,GeoPandas 更像“带空间能力的表格分析工具”。
本文以一个常见任务为主线:用 Python 读取一个行政区划 Shapefile,查看属性、筛选要素、保存结果,并解释什么时候应该用 Fiona,什么时候应该用 GeoPandas。

引言:先看一个最小可运行例子
假设你有一个行政区划文件:
data/county.shp
用 Fiona 读取时,通常是逐条遍历要素:
import fiona
with fiona.open("data/county.shp", "r", encoding="utf-8") as src:
print(src.crs)
print(src.schema)
for feature in src:
print(feature["properties"])
print(feature["geometry"]["type"])
break
用 GeoPandas 读取时,通常是一次性读成一个 GeoDataFrame,也就是带几何列的表格:
import geopandas as gpd
gdf = gpd.read_file("data/county.shp")
print(gdf.crs)
print(gdf.head())
print(gdf.geometry.geom_type.value_counts())
从这个例子可以看出,Fiona读取地理数据时更接近文件本身的要素结构,而 GeoPandas 更接近 pandas 表格分析思路。
背景:为什么 Fiona 和 GeoPandas 经常被放在一起比较
在 Python GIS 生态中,Fiona 和 GeoPandas 的关系非常紧密。很多时候你调用的是 geopandas.read_file(),但背后实际可能会通过 Fiona 或 pyogrio 这类引擎去读取矢量文件。也就是说,GeoPandas 面向用户提供高级接口,而 Fiona 更接近数据源驱动层。
这也是很多初学者困惑的原因:既然 GeoPandas 能读 Shapefile、GeoJSON、GeoPackage,那还需要 Fiona 吗?答案是:看任务类型。
- 如果你要做属性筛选、空间连接、缓冲区、叠加分析,优先用 GeoPandas。
- 如果你要逐条读取超大文件、检查 schema、控制字段类型、写入驱动格式,Fiona 更直接。
- 如果你只是想快速把矢量数据转成表格并分析,GeoPandas 更省事。
- 如果你需要了解矢量文件的底层结构,Fiona 更适合学习和调试。
原理:Fiona读取地理数据到底读到了什么
Fiona 读取矢量数据时,返回的不是 pandas 表格,而是类似 GeoJSON Feature 的结构。每一条要素通常包含三部分:
- id:要素编号。
- properties:属性字段和值。
- geometry:几何类型和坐标。
例如一条行政区要素可能长这样:
{
"id": "0",
"properties": {
"name": "示例县",
"code": "330101"
},
"geometry": {
"type": "Polygon",
"coordinates": [...]
}
}
而 GeoPandas 读取后得到的是 GeoDataFrame。你可以把它理解成一个普通 pandas DataFrame,只是多了一列特殊的 geometry,这一列存放点、线、面等空间几何对象。
import geopandas as gpd
gdf = gpd.read_file("data/county.shp")
print(type(gdf))
print(gdf.columns)
print(gdf.geometry.name)
因此,Fiona读取地理数据的重点是“读写要素”,GeoPandas 的重点是“分析空间表格”。
步骤:用 Fiona 读取、筛选并保存地理数据
步骤 1:查看数据驱动、坐标系和字段结构
使用 Fiona 时,建议先检查数据的坐标系和 schema。schema 可以理解为矢量图层的字段结构和几何类型定义。
import fiona
input_path = "data/county.shp"
with fiona.open(input_path, "r", encoding="utf-8") as src:
print("驱动:", src.driver)
print("坐标系:", src.crs)
print("字段结构:", src.schema)
print("要素数量:", len(src))
这一步非常适合排查 Shapefile 字段乱码、几何类型不一致、坐标系缺失等问题。
步骤 2:逐条读取要素
Fiona 的一个优势是可以逐条读取,不一定要把整个文件一次性放进内存。
with fiona.open(input_path, "r", encoding="utf-8") as src:
for feature in src:
props = feature["properties"]
geom = feature["geometry"]
print(props)
print(geom["type"])
break
如果你的文件很大,只需要扫描部分字段,Fiona读取地理数据会比直接加载为 GeoDataFrame 更可控。
步骤 3:按属性筛选要素
下面示例筛选名称字段中包含“区”的要素,并写入新的 GeoPackage 文件。
import fiona
input_path = "data/county.shp"
output_path = "data/county_filtered.gpkg"
with fiona.open(input_path, "r", encoding="utf-8") as src:
meta = src.meta.copy()
with fiona.open(
output_path,
"w",
driver="GPKG",
layer="county_filtered",
crs=src.crs,
schema=src.schema,
encoding="utf-8"
) as dst:
for feature in src:
name = feature["properties"].get("name", "")
if "区" in name:
dst.write(feature)
这个例子体现了 Fiona 的典型用法:保持原始 schema,逐条判断,逐条写出。
步骤:用 GeoPandas 完成同样的任务
步骤 1:读取为 GeoDataFrame
如果你更关心分析和筛选,GeoPandas 的代码会更短。
import geopandas as gpd
gdf = gpd.read_file("data/county.shp")
print(gdf.head())
print(gdf.crs)
步骤 2:按属性筛选
filtered = gdf[gdf["name"].str.contains("区", na=False)]
print(filtered[["name", "geometry"]].head())
步骤 3:保存结果
filtered.to_file(
"data/county_filtered.gpkg",
layer="county_filtered",
driver="GPKG"
)
对于普通 GIS 数据处理任务,GeoPandas 代码更接近“读表、筛选、保存”的思路。尤其是当你熟悉 pandas 时,GeoPandas 会更容易上手。
常见坑:Fiona读取地理数据时容易遇到的问题
1. Shapefile 中文字段或属性乱码
Shapefile 编码历史包袱较多,中文乱码很常见。可以尝试显式指定编码:
with fiona.open("data/county.shp", "r", encoding="utf-8") as src:
for feature in src:
print(feature["properties"])
break
如果 utf-8 不对,可以根据数据来源尝试 gbk。更推荐的做法是把长期使用的数据转换为 GeoPackage,减少 Shapefile 编码和字段长度限制带来的问题。
2. Fiona 读出来的是 dict,不是 DataFrame
这是设计差异,不是错误。Fiona 返回的是一条条 feature。你不能直接使用 gdf["字段名"] 这种 pandas 写法。
如果你需要表格操作,可以把要素整理为列表,或者直接使用 GeoPandas:
import geopandas as gpd
gdf = gpd.read_file("data/county.shp")
3. 写出文件时 schema 不匹配
Fiona 写文件时字段类型必须符合 schema。比如 schema 中某个字段是整数,你却写入字符串,就可能报错或写入失败。
with fiona.open("data/county.shp", "r", encoding="utf-8") as src:
print(src.schema)
写出前先检查 schema,是 Fiona 工作流中很重要的一步。
4. 坐标系缺失导致后续分析不准
Fiona 和 GeoPandas 都能读取 CRS,也就是坐标参考系统。但如果源数据本身没有正确的坐标系定义,软件并不会自动知道它到底是 WGS84、CGCS2000 还是某个投影坐标系。
如果后续要计算面积、长度或做叠加分析,一定要先确认坐标系。
方法比较:Fiona 与 GeoPandas 到底怎么选
| 比较项 | Fiona | GeoPandas |
|---|---|---|
| 核心定位 | 矢量数据底层读写接口 | 空间数据表格分析工具 |
| 返回对象 | 逐条 feature,类似 GeoJSON 结构 | GeoDataFrame |
| 适合任务 | 检查 schema、流式读取、格式转换、精细控制写出 | 属性筛选、空间分析、空间连接、制图预处理 |
| 学习门槛 | 需要理解 feature、schema、driver | 熟悉 pandas 的用户更容易上手 |
| 大文件处理 | 逐条读取更可控 | 通常会整体加载到内存 |
| 空间分析能力 | 本身不负责复杂空间分析 | 提供缓冲区、叠加、裁剪、空间连接等能力 |
| 典型代码 | fiona.open() |
gpd.read_file() |
如果你只是问“Fiona 和 GeoPandas 哪个更好”,这个问题本身不够准确。更实用的判断方式是:
- 要读取后马上做空间分析:选 GeoPandas。
- 要检查或控制矢量文件结构:选 Fiona。
- 要逐条处理很大的矢量数据:优先考虑 Fiona。
- 要和 pandas 统计分析结合:选 GeoPandas。
- 要写教学代码理解 GIS 文件结构:Fiona 很有价值。
检查清单:选择 Fiona 还是 GeoPandas 前先确认这些问题
- 你的目标是“读写文件”还是“空间分析”?读写偏 Fiona,分析偏 GeoPandas。
- 数据量是否大到不能一次性加载进内存?如果是,优先考虑 Fiona 的逐条读取方式。
- 是否需要保留原始字段类型和图层 schema?如果需要,Fiona 更直接。
- 是否需要执行缓冲区、裁剪、叠加、空间连接?如果需要,GeoPandas 更合适。
- 是否熟悉 pandas?如果熟悉,GeoPandas 的学习成本更低。
- 是否遇到编码、字段长度、驱动格式问题?可以用 Fiona 先检查数据结构。
- 是否需要长期保存中间成果?优先考虑 GeoPackage,而不是继续堆 Shapefile。
FAQ:Fiona读取地理数据与 GeoPandas 常见问题
Fiona读取地理数据能不能直接转成 GeoPandas?
可以。最简单的方式通常是直接用 GeoPandas 读取同一个文件。如果你已经用 Fiona 拿到了 feature 列表,也可以再构造成 GeoDataFrame,但多数场景没有必要绕一圈。
import geopandas as gpd
gdf = gpd.read_file("data/county.shp")
GeoPandas 是否完全替代 Fiona?
不能简单说完全替代。GeoPandas 更适合分析,Fiona 更适合底层读写和结构检查。对于 GIS 工程项目,二者经常配合使用:先用 Fiona 排查数据格式问题,再用 GeoPandas 做分析处理。
Fiona 可以做缓冲区分析吗?
Fiona 本身不负责缓冲区分析。缓冲区这类几何运算通常由 Shapely 或 GeoPandas 完成。Fiona 可以负责读入和写出,几何处理交给其他库。
为什么 GeoPandas 读取大文件会慢或占内存?
GeoPandas 通常会把数据加载成 GeoDataFrame,属性和几何对象都进入内存。如果数据量很大,内存压力会明显增加。此时可以考虑 Fiona 逐条处理,或把数据导入 PostGIS 后用数据库完成筛选和空间查询。
Fiona 和 GDAL/OGR 是什么关系?
Fiona 是 Python 中常用的矢量数据读写库,它的能力与 GDAL/OGR 生态密切相关。你可以把 GDAL/OGR 理解为底层地理数据格式支持体系,Fiona 提供了更符合 Python 使用习惯的接口。
新手应该先学 Fiona 还是 GeoPandas?
如果目标是快速完成 GIS 数据分析,建议先学 GeoPandas。如果目标是理解矢量文件结构、字段 schema、驱动格式和数据写出细节,再学习 Fiona。实际工作中,两者都值得掌握。
结论:把 Fiona 当作读写接口,把 GeoPandas 当作分析工具
回到“Fiona读取地理数据?与GeoPandas啥区别?”这个问题,最实用的结论是:Fiona 偏底层,GeoPandas 偏分析。Fiona读取地理数据时,你面对的是 feature、schema、driver 和 CRS;GeoPandas 读取数据后,你面对的是 GeoDataFrame、属性列和 geometry 列。
如果你要写一个稳定的数据转换脚本,尤其需要逐条处理、检查字段结构和控制输出格式,Fiona 很合适。如果你要做筛选、统计、空间连接、缓冲区、叠加分析,GeoPandas 会更高效。真正的 Python GIS 工作流不是二选一,而是根据任务把两者放在合适的位置。