基于Dask将多幅TIF文件合并为NetCDF/Zarr数据立方体
使用Dask合并多日期TIF文件为Zarr/NetCDF数据立方体(避免内存溢出)
问题描述
我有一个存储.tif文件的文件夹,需要将这些文件合并成NetCDF或Zarr格式的数据立方体,方便在Python中读取为3D数组。这些文件的特点是:
- 空间上无重叠,拼接后覆盖一片大区域
- 文件按日期命名,部分文件日期相同,这类同日期的文件需要按
x维度拼接 - 目标是合并为单个数据集并保存,必须使用Dask避免内存溢出问题
解决方案代码
import xarray as xr import pandas as pd from collections import Counter # 日期列表,其中2014-10-15对应3个文件 list_dates = [ pd.Timestamp('2014-10-08 00:00:00'), pd.Timestamp('2014-10-13 00:00:00'), pd.Timestamp('2014-10-15 00:00:00'), pd.Timestamp('2014-10-15 00:00:00'), pd.Timestamp('2014-10-15 00:00:00') ] # 文件列表,最后3个文件属于同一日期 list_files = [ '2014-10-08_0.tif', '2014-10-13_0.tif', '2014-10-15_0.tif', '2014-10-15_1.tif', '2014-10-15_2.tif' ] # 统计每个日期出现的次数 date_counts = Counter(list_dates) # 存储处理后的DataArray data_arrays = [] i = 0 while i < len(list_files): current_date = list_dates[i] count = date_counts[current_date] # 处理单文件日期:用Dask分块打开,避免加载全部到内存 if count == 1: # 指定chunks启用Dask延迟加载,可根据文件大小调整分块尺寸 da_single = xr.open_dataarray(list_files[i], chunks={'x': 1024, 'y': 1024}) # 移除多余的band维度(如果TIF是单波段) if 'band' in da_single.dims: da_single = da_single.squeeze('band') # 添加时间维度 da_single = da_single.expand_dims(time=[current_date]) data_arrays.append(da_single) i += 1 # 处理多文件同日期:先按x维度拼接空间分片 else: # 批量打开同日期的所有文件,均使用Dask分块 date_files = list_files[i:i+count] da_list = [] for f in date_files: da_chunk = xr.open_dataarray(f, chunks={'x': 1024, 'y': 1024}) if 'band' in da_chunk.dims: da_chunk = da_chunk.squeeze('band') da_list.append(da_chunk) # 按x维度拼接空间分片,Dask会自动处理延迟计算 da_concat_x = xr.concat(da_list, dim='x') # 添加时间维度 da_concat_x = da_concat_x.expand_dims(time=[current_date]) data_arrays.append(da_concat_x) i += count # 按时间维度合并所有日期的数据集 final_ds = xr.concat(data_arrays, dim='time') # 保存为Zarr格式(推荐大文件场景,支持分块存储和并行读写) final_ds.to_zarr('merged_data_cube.zarr', mode='w', consolidated=True) # 若需保存为NetCDF,需确保分块设置合理(适合NetCDF的分块大小) # final_ds.to_netcdf('merged_data_cube.nc', mode='w', format='NETCDF4') print(final_ds)
关键说明
- Dask分块加载:打开TIF时指定
chunks参数,让xarray用Dask延迟加载数据,避免一次性将所有文件读入内存。分块尺寸可根据文件大小、内存情况调整(如1024x1024)。 - 单波段维度处理:多数单波段TIF打开后会带有
band维度,通过squeeze('band')移除该维度,确保数据为2D(x,y)结构后再扩展时间维度。 - 同日期空间拼接:同日期的分片文件按
x维度拼接,Dask将操作转为延迟任务,不会立即执行计算,避免内存峰值。 - 存储格式选择:
- Zarr:优先推荐,适合超大规模数据集,支持分块存储与并行读写,后续读取可继续使用Dask延迟加载。
- NetCDF:适用于中等规模数据,保存时需确保分块设置合理,避免单块过大引发内存问题。
- 延迟计算机制:整个流程中大部分操作为延迟执行,仅在保存或调用
compute()时才会实际计算,有效控制内存占用。
内容的提问来源于stack exchange,提问作者Nihilum
相关产品推荐
相关产品推荐

