python fiona

张开发
2026/4/15 20:26:49 15 分钟阅读

分享文章

python fiona
# 聊聊Geopandas当Python遇见地理空间数据如果你曾经在地图上画过点、描过线或者处理过行政区划的边界数据大概能体会到这类工作的繁琐。传统的地理信息系统软件功能强大但往往笨重且不易集成到自动化流程里。后来人们开始用Python处理数据自然也希望用同样的工具来摆弄地图。Geopandas的出现恰好填补了这个空白。简单来说Geopandas让Python具备了处理地理空间数据的能力。它不是什么全新的发明而是把几个已有的工具巧妙地整合在了一起。底层依赖着Shapely进行几何计算Fiona读写文件Matplotlib绘图再套上Pandas那套熟悉的数据框接口。这种组合看似简单却非常实用让熟悉Pandas的人几乎可以无门槛地开始处理地理数据。他能做什么日常工作中很多看似和地图无关的数据其实都藏着地理位置信息。比如客户的地址、物流的路线、气象站的坐标这些数据一旦落到地图上往往能看出新的模式。Geopandas的核心是扩展了Pandas的DataFrame增加了一个叫geometry的列。这列不存放普通的数字或文字而是点、线、面这些几何对象。你可以想象成在普通的表格旁边挂了一张透明的硫酸纸纸上画着对应的图形。有了这个基础很多操作就变得直观了。比如计算两个区域是否相邻在Geopandas里就是一句空间连接spatial join的事情测量距离也不再需要自己写公式直接调用方法就行。更实用的是它能轻松地把处理结果画出来从简单的散点图到复杂的 choropleth 地图那种按区域填色的地图都能胜任。曾经有个项目需要分析城市里不同区域的人口密度和公园分布的关系。传统做法可能要在不同软件间倒腾数据用Geopandas之后所有清洗、计算、可视化都在同一个Jupyter笔记本里完成了。虽然处理大规模数据时速度不算最快但对于大多数分析场景已经足够。怎么上手使用安装Geopandas有时会让人头疼主要是依赖库比较多。用conda安装通常比pip顺利些如果遇到问题往往不是Geopandas本身而是某个底层库的编译问题。数据读取非常简单常见的shapefile、GeoJSON文件一行gpd.read_file()就能搞定。这里有个细节shapefile其实是一组文件但只需要指定.shp那个主文件就行。读进来的就是一个GeoDataFrame行为和Pandas的DataFrame几乎一样只是多了些地理相关的方法。空间查询是常用的功能。比如找出所有在某个公园5公里范围内的地铁站用within()或distance()方法组合一下就能实现。空间连接更是利器它能把两个图层按位置关系合并比如把人口统计数据和行政区划边界关联起来。绘图只需要调用plot()方法参数设置和Matplotlib很像。如果想画得好看些可以调整颜色、边框、图例这些元素。导出结果也很方便可以存成新的地理文件或者导出为图片、PDF。一些实践中的体会刚开始用的时候容易把所有数据都读进内存遇到大文件就卡住了。后来学乖了先看文件大小和属性数量太大的就用边界框bbox或属性查询裁剪出需要的部分。坐标系也是个容易踩坑的地方不同来源的数据可能用不同的坐标参考系CRS不统一的话计算距离面积都会出错。通常先统一成投影坐标系比如UTM再进行计算比较稳妥。几何对象的有效性偶尔会带来问题。比如一个多边形理论上应该闭合但实际数据里可能有开口或者边界线自相交形成所谓的“蝴蝶结”形状。这类数据在绘图时可能看不出问题但做空间运算就会报错。is_valid和buffer(0)这类方法可以用来检查和修复。性能方面如果数据量真的很大纯用Geopandas可能会比较慢。这时候可以配合Dask做并行或者用PostGIS这类数据库先做预处理。对于特别复杂的空间运算有时还是会回头用ArcGIS或QGIS毕竟专业工具在算法优化上更成熟。和同类工具的对比提到地理空间分析很多人会想到ArcGIS。它确实是行业标准界面友好、功能全面但商业授权费用不菲而且自动化程度相对低。QGIS是开源的替代品功能也很强大不过和Python的集成还是隔了一层。如果是简单的点位计算用Shapely配合Fiona也能完成但需要自己处理数据结构和绘图代码量会多不少。如果是做网络分析或地形处理可能要用到NetworkX或GDAL这些更专门的库。Geopandas的定位很清晰它不是为了取代专业GIS软件而是在Python生态里提供一个够用且好用的地理数据处理入口。对于数据分析师、研究人员、需要把地理分析集成到Web应用里的开发者来说它# ## 聊聊 Python 里的 Fiona一个处理地理空间数据的老朋友如果你经常和地理数据打交道比如那些带着经纬度信息的矢量文件那你可能早就听说过 Fiona 这个名字。它不是那种让人眼前一亮的明星库更像是一个在后台默默干活、极其可靠的工具。很多人在用但未必会专门为它写篇文章。今天就从日常使用的角度拆开看看这个库到底是怎么回事。它到底是什么简单说Fiona 是 Python 里一个专门用来读写地理空间矢量数据文件的库。所谓矢量数据你可以想象成地图上那些具体的“形状”比如一个国家版图的多边形边界、一条河流的蜿蜒线、或者一个城市里各个地铁站的点。这些数据通常被保存在像 Shapefile、GeoJSON 这类格式的文件里。Fiona 的核心任务就是充当 Python 和这些格式文件之间的一个“翻译官”。它的底层其实依赖着开源地理空间基金会OSGeo的 GDAL/OGR 库那可是地理信息系统的基石之一。但 Fiona 用 Python 的风格把那些复杂的 C/C 接口包装了起来让你不用去啃那些艰涩的底层细节能用更符合 Python 习惯的方式比如迭代器、字典来轻松操作数据。它给自己的定位很清晰只做读写不做分析。就像一个尽职的图书馆管理员只负责把书数据准确地存进去、取出来至于你拿这本书是做研究、消遣还是当枕头它一概不管。分析的事情它交给像 Shapely、GeoPandas 这样的伙伴去做。它能帮你做什么日常工作里Fiona 最常出场的场景就是数据转换和预处理。比如你从某个政府公开数据网站下载了一个 Shapefile 包里面有一堆.shp,.dbf,.prj文件。你的任务可能是把这些数据读出来过滤出某个特定省份的数据或者把坐标系从传统的“北京54”转换成通用的 WGS84也就是 GPS 常用的经纬度然后再存成 GeoJSON 格式方便在网页地图上展示。又或者你手头有一份 CSV 文件里面记录了全国所有连锁咖啡店的门店地址和经纬度。你想把这些点数据变成正式的地理空间文件以便在地图软件里打开查看或者进行空间查询比如找出某个小区 1 公里内有多少家店。这时候用 Fiona 读取 CSV虽然它更擅长标准空间格式但配合其他库处理文本后用它写入是没问题的然后写成 Shapefile 或 GeoJSON就是很自然的流程。它特别适合那些自动化处理流水线。比如你需要定期从 FTP 服务器拉取最新的行政区划数据做清洗和转换后推送到数据库。用 Fiona 写几行脚本挂在定时任务上这个流程就完全不用人工干预了。怎么把它用起来用 Fiona 的第一步通常是打开一个数据源。这非常直观感觉就像用内置的open()函数一样。importfiona# 打开一个 Shapefile 文件withfiona.open(roads.shp,r)assource:# 现在 source 就是一个类似文件句柄的集合# 可以看看里面有多少条记录要素print(f总共有{len(source)}条道路)# 可以看看第一条记录长什么样first_featurenext(iter(source))print(first_feature[geometry])# 几何形状比如线的坐标串print(first_feature[properties])# 属性比如道路名称、等级这里有个细节值得注意fiona.open()返回的集合在读取时会自动重置迭代器。所以上面先len(source)再next(iter(source))是没问题的。这种设计避免了新手常掉的一个坑——迭代一次之后集合就空了。写文件也同样简单。你需要先定义好输出的模式schema也就是告诉 Fiona 你要存的数据“长什么样”。# 假设我们要从 source 里筛选出一些数据写入新文件output_schemasource.schema.copy()# 沿用输入数据的结构withfiona.open(major_roads.geojson,w,driverGeoJSON,# 指定输出格式为 GeoJSONcrssource.crs,# 沿用原来的坐标系schemaoutput_schema)asdst:forfeatureinsource:# 只写入道路等级为高速或国道的要素iffeature[properties][road_class]in[高速,国道]:dst.write(feature)整个过程就是“打开-读取/处理-写入”的模式非常符合直觉。Fiona 把地理空间数据抽象成了“要素Feature”的集合每个要素包含几何图形字典表示和属性字典表示这让 Python 开发者感到非常亲切。一些实践中的心得用久了之后会发现一些让工作更顺畅的小技巧。首先务必使用上下文管理器with语句。地理数据文件特别是 Shapefile其实是一组文件。用with可以确保所有文件句柄都被正确关闭数据完整写入避免出现只有.shp主文件更新了而.dbf属性文件却没写进去的尴尬情况。其次在处理超大文件时要有内存意识。虽然可以一次性把数据全读进列表但更好的做法是保持迭代器的工作方式一边读一边处理一边写这样几乎不占什么额外内存。如果真需要随机访问再考虑用list(source)转成列表或者用更专业的空间数据库。关于坐标系CRS这是个容易出问题的地方。Fiona 读取数据时会尽量解析文件的坐标系信息保存在crs属性里。但有时文件里的信息可能是错的或者缺失。在写入新文件时如果对坐标系有严格要求比如必须用 WGS84最好显式地指定crsepsg:4326而不是依赖自动推断。GDAL 的坐标系数据库有时会和你的预期有微妙差别。数据验证也是个好习惯。在写入大量数据前可以先用一两条样本数据测试一下写入流程是否正常定义的 schema 是否正确。Fiona 在写入时如果遇到几何图形不合法比如自相交的多边形可能会报错。提前用 Shapely 库的.is_valid方法做下检查能省去很多麻烦。和身边的其他工具比一比既然说到处理空间数据就免不了要提 GeoPandas。很多人第一个问题就是我该用 Fiona 还是 GeoPandas这其实不是二选一的问题。GeoPandas 是建立在 Fiona和 Shapely之上的。你可以把 GeoPandas 想象成一个功能强大的“数据分析工作站”它把数据读成类似 Pandas 的 DataFrame可以非常方便地进行属性筛选、空间连接、制图可视化等复杂操作。如果你要做探索性分析或者复杂的空间运算GeoPandas 是首选。而 Fiona 则像是这个工作站里的“专用文件接口模块”。它的优势在于轻量和专注。当你的任务仅仅是格式转换、数据提取或者需要嵌入到一个对依赖库非常敏感的轻量级应用里时直接用 Fiona 会更干净启动更快依赖更少。它没有 GeoPandas 那么全能的 API但也因此没有那么多“包袱”。另一个常被比较的是ogrGDAL 的 Python 绑定。OGR 功能极其强大几乎支持所有空间格式是真正的“瑞士军刀”。但它的 API 是 C 风格的用起来比较冗长和底层。Fiona 可以看作是 OGR 的一个“Pythonic 皮肤”它牺牲了 OGR 一小部分极其冷门的功能换来了十倍以上的易用性。对于 95% 的常见读写任务Fiona 的代码写起来更简洁更不容易出错。所以选择哪个工具取决于你的任务场景。简单的读写和转换Fiona 直截了当需要做复杂分析和操作就上 GeoPandas如果你遇到一个非常古怪的数据格式或者需要深度调优性能那可能就得请出 OGR 这把“重型武器”了。总的来说Fiona 在 Python 的地理空间生态里扮演着一个坚实、可靠的基础角色。它不炫酷但不可或缺。当你需要安静、高效地和那些地图数据文件打交道时它总是那个值得信赖的选择。降低了门槛。很多任务不用再切换不同软件直接在熟悉的Python环境里就能完成从数据处理到可视化的全流程。说到底工具的选择取决于具体场景。如果只是偶尔需要在地图上标几个点在线地图的API可能更快捷如果要处理全国级别的遥感影像专门的GIS平台更合适。而在日常的数据分析工作中当表格里的数据需要和地图结合时Geopandas那种“刚刚好”的平衡感用起来确实顺手。

更多文章