使用rasterio调整栅格数组时如何限制数值小数位数
栅格百分比转换小数位限制方案
问题说明
多幅栅格影像的像元值均为对应指标的计数结果,需将计数值转换为百分比格式。现有代码可完成基础百分比转换,但计算结果存在过多冗余小数位(如33.33333333),由于栅格数据体量较大,冗余小数位会大幅提升输出文件体积,而实际业务场景无需保留高精度小数,需限制输出栅格数组的数值小数位数。
原有实现代码:
import rasterio as rio def Percentage(path_in, granule): path_out = os.path.join(certain_path, granule + ".jp2") for granule in glob.glob(r"path_to_rasters\*"): with rio.open(path_in) as src: # 读取为numpy数组 array = src.read() profile = src.profile array = (array / count) * 100 with rio.open(path_out, 'w', **profile) as dst: # 写入磁盘 dst.write(array)
实现方法
小数位控制和文件体积压缩需要配合两处修改,仅做数值四舍五入不调整存储类型的话,无法实际降低文件体积:
- 数值计算完成后,调用numpy的
np.round()方法对数组做四舍五入,通过decimals参数指定需要保留的小数位数,可按需设置为0(整数)、1、2等 - 调整输出栅格的配置参数,将数据类型从默认的64位浮点型替换为匹配精度的低精度类型:保留小数时使用
float32即可满足常规业务精度要求;若仅需整数百分比,直接使用uint8类型即可(取值范围0-255,完全覆盖0-100的百分比区间),单像元存储占用可降至原float64类型的1/8,压缩效果显著。
修正后的可运行代码如下:
import rasterio as rio import os import glob import numpy as np # 按需调整保留的小数位数 DECIMAL_PLACES = 2 # 根据保留精度选择对应输出数据类型:保留小数选float32,整数百分比选uint8 OUT_DTYPE = "float32" def batch_convert_percentage(input_dir, output_path): # 遍历输入目录下所有栅格文件 for granule_path in glob.glob(os.path.join(input_dir, "*")): granule_name = os.path.basename(granule_path).split('.')[0] path_out = os.path.join(output_path, granule_name + ".jp2") with rio.open(granule_path) as src: array = src.read() profile = src.profile # 计算百分比 array = (array / count) * 100 # 按指定位数四舍五入并转换为目标数据类型 array = np.round(array, decimals=DECIMAL_PLACES).astype(OUT_DTYPE) # 更新输出栅格配置 profile.update(dtype=OUT_DTYPE) with rio.open(path_out, 'w', **profile) as dst: dst.write(array)
补充说明:如果选择输出整数百分比,把
DECIMAL_PLACES设为0,OUT_DTYPE设为uint8即可,此时文件体积压缩效果最明显。如果使用JP2格式输出,还可以在profile里添加JP2K压缩相关参数进一步缩小体积,不会影响数值精度。
内容的提问来源于stack exchange,提问作者Niek
相关产品推荐
相关产品推荐

