You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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)

关键说明

  1. Dask分块加载:打开TIF时指定chunks参数,让xarray用Dask延迟加载数据,避免一次性将所有文件读入内存。分块尺寸可根据文件大小、内存情况调整(如1024x1024)。
  2. 单波段维度处理:多数单波段TIF打开后会带有band维度,通过squeeze('band')移除该维度,确保数据为2D(x,y)结构后再扩展时间维度。
  3. 同日期空间拼接:同日期的分片文件按x维度拼接,Dask将操作转为延迟任务,不会立即执行计算,避免内存峰值。
  4. 存储格式选择:
    • Zarr:优先推荐,适合超大规模数据集,支持分块存储与并行读写,后续读取可继续使用Dask延迟加载。
    • NetCDF:适用于中等规模数据,保存时需确保分块设置合理,避免单块过大引发内存问题。
  5. 延迟计算机制:整个流程中大部分操作为延迟执行,仅在保存或调用compute()时才会实际计算,有效控制内存占用。

内容的提问来源于stack exchange,提问作者Nihilum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 20:05:59