Python 用 rasterio 读大栅格:窗口读取、分块处理与内存控制

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

问题场景

很多 Python 栅格脚本在小样本上能跑,一换成真正的大影像就直接内存爆炸。原因通常很简单:代码默认把整幅栅格一次性读进了内存。几十 MB 的 DEM 没问题,几 GB 的遥感影像就会立刻变成事故现场。

用 rasterio 处理大栅格时,核心不是“读得出来”,而是“按块读、按块算、按块写”。窗口读取是第一步,分块处理和结果写回才是完整方案。

核心原理与判断框架

rasterio 支持通过 `window` 读取局部数据。适用于局部裁剪、滑窗分析、分块重采样和批量统计。判断是否必须用窗口读取,主要看数据体量、机器内存和算法是否可分块。

数据规模 处理建议 风险
小栅格 可整幅读取 代码简单但扩展性差
大栅格 窗口或分块处理 一次性读取易爆内存
超大影像 分块 + 流式写出 IO 与内存都要控制

实操流程

import rasterio
from rasterio.windows import Window

with rasterio.open("big.tif") as src:
    window = Window(0, 0, 1024, 1024)
    arr = src.read(1, window=window)
  1. 先读取影像尺寸、波段数和块大小,判断是否需要分块。
  2. 按窗口循环读取,而不是一次性 `read()` 全部波段。
  3. 中间结果尽量就地计算,避免额外复制大数组。
  4. 输出时按窗口写回新栅格。

项目避坑与质量检查

窗口处理最容易错的是边界块。最后一行、最后一列的块尺寸可能不满,循环时要显式处理。

同时,按窗口处理后要检查输出拼接是否完整,特别是行列数、仿射变换和 NoData 是否保持一致。

FAQ

为什么代码在小图上没问题,大图就崩?

因为整幅读取的内存占用会按像元数线性增长,大图很快超出机器内存。

窗口大小越大越好吗?

不一定。太大仍会占内存,太小则增加 IO 开销,需要平衡。

分块处理会影响结果吗?

只要算法支持分块且边界处理正确,结果应与整幅处理一致。

总结

大栅格处理的关键是控制内存峰值。`rasterio` 的窗口读取让脚本从“只能跑样本”变成“能跑生产数据”,前提是边界和输出一致性也一起管住。