如何从大型NetCDF4文件提取单个变量并保存为独立NetCDF4文件
超大型NetCDF文件单变量提取保存方案
方案1:使用你当前已引入的netCDF4库实现(无需额外安装依赖)
全程不会将全量数组加载到内存,避免触发大小限制报错,代码示例如下:
import netCDF4 # 打开原文件,不要提前将变量读入内存,保持文件句柄处于打开状态 with netCDF4.Dataset("2020_original_Map.1.1.nc", 'r') as src_ds: # 获取目标变量 src_var = src_ds.variables['lccs_class'] # 新建输出nc文件 with netCDF4.Dataset("lccs_class_only.nc", 'w') as dst_ds: # 第一步:复制目标变量关联的所有维度到新文件 for dim_name in src_var.dimensions: dim = src_ds.dimensions[dim_name] dst_ds.createDimension(dim_name, size=None if dim.isunlimited() else len(dim)) # 同时复制对应维度的坐标变量,保证新文件保留地理/时间坐标信息可正常使用 if dim_name in src_ds.variables: src_coord = src_ds.variables[dim_name] dst_coord = dst_ds.createVariable(dim_name, src_coord.dtype, src_coord.dimensions, zlib=getattr(src_coord, 'zlib', False)) # 复制坐标变量的属性 dst_coord.setncatts(src_coord.__dict__) # 坐标数据量极小,直接写入不会爆内存 dst_coord[:] = src_coord[:] # 第二步:创建目标变量,保留原变量的压缩、填充值等配置 dst_var = dst_ds.createVariable( 'lccs_class', src_var.dtype, src_var.dimensions, zlib=getattr(src_var, 'zlib', False), complevel=getattr(src_var, 'complevel', 4), fill_value=getattr(src_var, '_FillValue', None) ) # 复制原变量的所有属性,包含单位、分类说明等元信息 dst_var.setncatts(src_var.__dict__) # 第三步:分块写入数据,避免全量加载到内存,可根据设备内存调整chunk_size大小 chunk_size = 1000 for i in range(0, src_var.shape[0], chunk_size): end = min(i + chunk_size, src_var.shape[0]) dst_var[i:end, :] = src_var[i:end, :]
如果目标变量是带时间维度的三维数据,调整分块逻辑对应时间维度即可。
方案2:使用xarray实现(代码更简洁,自动处理分块和元信息)
如果可安装额外依赖,xarray的操作逻辑更简单,打开文件时指定仅读取目标变量,不会加载其他冗余数据:
import xarray as xr # 打开原文件时仅读取lccs_class变量和关联坐标,不会加载全文件 ds = xr.open_dataset("2020_original_Map.1.1.nc", variables=['lccs_class'], engine='netcdf4') # 直接导出到新文件,自动处理分块、压缩和元信息 ds.to_netcdf("lccs_class_only.nc") ds.close()
该方案底层依然基于netCDF4实现,同样不会触发全量数组加载的内存报错。
内容的提问来源于stack exchange,提问作者Maya WillStep
相关产品推荐
相关产品推荐

