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

如何用Python将多份3D NetCDF合并为带模型维度的4D文件并计算月累计降水

解决CMIP6多模型NetCDF合并为4D数据集并计算月累计降水的问题

问题背景

需要合并9个不同气候模型的3D(time, lat, lon)NetCDF降水数据(变量pr),生成包含model维度的4D数据集,同时解决重采样时的ValueError: index must be monotonic for resampling错误,最终计算月累计降水。

当前代码合并后得到的是3D数据集,未保留模型维度,且时间索引不单调导致重采样失败。

错误原因

  • 未保留模型维度:原代码用xr.combine_nested(netcdfs, concat_dim="time")把所有模型的时间维度直接拼接,导致模型信息丢失,变成单一3D数据集。
  • 时间索引不单调:多个模型的时间序列被无序拼接,导致time维度的索引不是严格递增的,触发重采样的单调索引要求错误。

修改后完整代码

import xarray as xr
import os
from pathlib import Path

variables = ['pr']         
scenarios = ['historical', 'ssp245']        # 可选值:['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585']
models = ['UKESM1-0-LL', 'MRI-ESM2-0', 'MIROC6', 'MIROC-ES2L', 'IPSL-CM6A-LR',
         'GFDL-ESM4', 'FGOALS-g3', 'CNRM-ESM2-1', 'CanESM5']

processing_fn = Path("/your/actual/processing/path")  # 替换为你的实际数据路径

for variable in variables:
    # 修正保存路径:移至variable循环内,确保使用当前变量值
    save_folder = processing_fn / 'local_climate_assessment' / f'{variable}' / 'output'
    if not os.path.exists(save_folder):
        os.makedirs(save_folder)
    
    model_datasets = []
    
    # 遍历每个模型,加载并标记模型/情景维度
    for scenario in scenarios:
        for model in models:
            source = processing_fn / 'local_climate_assessment' / f'{variable}' / f'{scenario}' / f'{model}'
            netcdf_fn = save_folder / f'{variable}_{scenario}_{model}.nc'
            
            if not os.path.exists(netcdf_fn):
                # 合并单模型年度文件,强制按时间排序
                ds_model = xr.open_mfdataset(
                    str(source / '*.nc'),
                    combine='nested',
                    concat_dim="time",
                    use_cftime=True,
                    data_vars='minimal',
                    coords='minimal',
                    compat='override'
                ).sortby('time')
                ds_model.to_netcdf(netcdf_fn)
                print(f"已保存单模型文件:{netcdf_fn}")
            else:
                ds_model = xr.open_dataset(netcdf_fn, use_cftime=True).sortby('time')
            
            # 新增model和scenario维度,保留模型与情景信息
            ds_model = ds_model.expand_dims({'model': [model], 'scenario': [scenario]})
            model_datasets.append(ds_model)
    
    # 按model维度拼接所有数据集,生成4D结构
    combined_ds = xr.concat(model_datasets, dim='model')
    print("\n合并后的4D数据集信息:")
    print(combined_ds)
    
    # 计算月累计降水,确保时间索引单调
    monthly_pr = combined_ds.resample(time='M').sum(dim='time', skipna=True)
    
    # 保存月累计结果
    monthly_save_path = save_folder / f'{variable}_multi_model_monthly.nc'
    monthly_pr.to_netcdf(monthly_save_path)
    print(f"\n月累计降水已保存至:{monthly_save_path}")

关键修改说明

  • 新增模型/情景维度:
    • 用expand_dims()为每个单模型数据集添加model和scenario维度,保留元数据信息。
    • 使用xr.concat()按model维度拼接,最终生成维度为(model, scenario, time, lat, lon)的4D数据集。
  • 修复时间索引问题:
    • 加载每个模型数据后调用.sortby('time'),确保时间序列严格递增,满足重采样的单调索引要求。
  • 路径逻辑修正:
    • 将save_folder的定义移到variable循环内部,避免循环外引用未初始化的变量。
  • 月累计计算优化:
    • 加入skipna=True处理数据中的缺失值,避免累计结果出现无效值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 22:25:18