控制terra包SpatRaster内存占用:三类技术问题问询
SpatRaster数据类型与内存占用问题解答
实验过程
我创建了一个仅包含整数"1"的简单栅格:
r <- rast(matrix(rep(1, 100), nrow = 10))
该对象未关联数据类型:
datatype(r) # ""
我通过datatype = "FLT4S"将其写入磁盘后重新读取:
name.flt <- "test_FLT4S.tif" writeRaster(r, name.flt, datatype = "FLT4S") r.in.flt <- rast(name.flt)
同时也通过datatype = "INT1U"写入磁盘后重新读取:
name.int <- "test_INT1U.tif" writeRaster(r, name.int, datatype = "INT1U") r.in.int <- rast(name.int)
读取后的对象数据类型显示正确:
datatype(r.in.flt) # "FLT4S" datatype(r.in.int) # "INT1U"
对应的文件大小显示整数类型的文件尺寸更小:
file.size(name.flt) # 665 file.size(name.int) # 618
但在内存中,两个对象占用的内存大小一致:
object.size(r.in.flt) # 1304 bytes object.size(r.in.int) # 1304 bytes
问题解答
1. 为何初始创建的SpatRaster对象r没有关联数据类型?
用rast()从矩阵直接创建的SpatRaster是内存临时对象,此时还不需要绑定磁盘存储用的具体数据类型。datatype()返回空字符串,是因为这个属性只在对象被写入磁盘(指定类型)或者显式设置后才会被赋值。简单来说,内存中的初始状态不需要提前锁定磁盘格式,直到需要持久化或明确定义时才确定数据类型。
2. 是否可以为SpatRaster对象r设置数据类型?如何操作?
可以,有两种实用方法:
- 创建时直接指定
在rast()中通过datatype参数直接定义,比如设置为无符号8位整数(INT1U):r <- rast(matrix(rep(1, 100), nrow = 10), datatype = "INT1U") datatype(r) # "INT1U" - 转换现有对象
使用terra包的cast()函数转换已有SpatRaster的数据类型:
处理大型数据集时,根据数据取值范围选择最小的可用整数类型,能有效降低内存占用。r_int <- cast(r, "INT1U") datatype(r_int) # "INT1U"
3. 为何从"INT1U"格式文件读取的对象在R中并未占用更少内存?
这是因为object.size()统计的是R对象的表层结构大小,没有准确反映SpatRaster底层数据块的真实内存占用。另外,R本身没有原生的1字节整数类型,terra读取磁盘上的INT1U(1字节)数据时,会自动转换为R默认的32位整数(4字节)来处理,所以内存中两种类型的栅格数据块占用空间一致。
如果要真正节省内存,建议创建或转换SpatRaster时就指定合适类型,同时处理超大型栅格时优先用分块处理或保留磁盘连接(不加载全量数据到内存),这样能利用磁盘上的紧凑数据格式减少内存消耗。
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

