GeoPandas 读写 GeoParquet:空间分区、字段类型与跨工具验证

Python
Dr.GIS
wowwwai GIS研习社 · 工具流程与项目排障

GeoPandas 读写 GeoParquet:空间分区、字段类型与跨工具验证

当项目把几十个 GeoJSON 合成一份几 GB 的数据时,读取慢、字段类型漂移、服务端反复解析 JSON 很快都会成为瓶颈。GeoParquet 兼顾列式存储和空间元数据,适合分析与交换,但它不是把文件后缀改成 parquet 就结束。本文说明怎样用 GeoPandas 正确读写、怎样规划分区,以及如何验证其他工具读到的是同一份空间数据。

列式格式擅长按字段读取

Parquet 以列组织数据,读少量属性时不必扫描所有字段;但几何列仍有编码和反序列化成本。查询只需要属性时应明确 columns,不能因为格式快就整表读入内存。

空间分区要服务查询范围

按行政区、网格或时间切分都可行,关键是与常用过滤条件一致。分区过细会产生大量小文件,过粗又让 bbox 过滤失去意义;先从真实查询日志反推。

字段类型是交换契约

整数中的空值、日期时区、分类编码和列表字段,在不同工具间可能有不同表现。写入前要固定 schema,并对关键字段做读回检查。

GeoParquet 元数据不可省略

空间参考、几何类型和 bounding box 信息帮助下游识别数据。若文件只被当作普通 Parquet,空间查询和 CRS 判断都会失去依据。

可执行实操流程

  1. 先清理 GeoDataFrame:检查 geometry 是否为空或无效,统一 CRS,并为主键、日期、分类字段明确 dtype。
  2. 选择与访问方式对应的分区键,例如按年度和城市;统计每个分区行数与文件大小,避免形成极端倾斜分区。
  3. 用 to_parquet 写入一个小样本,再用 read_parquet 读回;比对 CRS、行数、主键集合、几何类型和关键统计量。
  4. 对大数据仅选择必要 columns,并在代表性 bbox 上测试读取时间和内存;记录机器配置与文件版本。
  5. 交付前分别用 GeoPandas 与第二个支持 GeoParquet 的工具打开,比较范围、字段名、空值数量及一处已知要素的坐标。
gdf = gdf.to_crs(3857)
gdf.to_parquet('roads.parquet', index=False)
check = gpd.read_parquet('roads.parquet', columns=['road_id', 'class', 'geometry'])
assert check.crs == gdf.crs

项目避坑与质量检查

真实项目里最危险的是把 pandas 的 object 列直接写出:其中混有数字、字符串和空列表时,不同读取端会给出不同类型。导出前应逐字段统计 Python 类型;无法定义稳定契约的字段拆到独立表或转成受控 JSON,而不是让它悄悄混在业务属性里。

检查阶段 必须保留的证据 异常处理
输入 CRS、几何有效性、字段 dtype 隔离异常样本,不直接覆盖源数据
处理 分区行数、文件大小与读回统计 回到参数、单位与筛选条件逐项复现
交付 跨工具打开结果和已知要素坐标 用独立样本或第二个环境复核

让流程能被下一位同事复跑

除数据文件外,保留 schema 说明、分区规则、生成脚本和读回校验结果。只有说明“按什么过滤最有效、空值代表什么”,下一位使用者才能避免把列式文件当成没有边界的万能交换格式。

源数据批次、坐标参考、关键参数、异常清单和前后统计放在同一份处理记录中。这样数据更新时,团队判断的是结果差异来自哪里,而不是重新猜测上一次做过什么。

FAQ

GeoParquet 能替代所有 GIS 格式吗?

不能。它很适合分析和列式交换;复杂编辑、样式和部分拓扑工作仍可能更适合 GeoPackage 或数据库。

为什么写出后整数列变成浮点?

通常是该列存在空值且未使用可空整数类型。应在写入前显式设置 pandas nullable integer dtype。

是否一定要做空间分区?

不一定。数据量和查询模式较简单时单文件更易维护;只有范围过滤或并行读取受益时再分区。

总结

GeoParquet 的价值不只是更小或更快,而是把空间数据的字段契约、分区策略和读回验证变成可维护的工程约定。