如何合并xarray.Dataset列表为单个NetCDF文件或Dataset?
问题:合并多个xarray Dataset为单个Dataset或NetCDF文件
问题背景
我用xarray遍历多个多维NetCDF文件,提取目标变量后得到了一个xarray.core.dataset.Dataset列表,现在需要把这个列表合并成单个可被xarray读取的Dataset或NetCDF文件。
现有代码
import glob import xarray as xr all_fwi = glob.glob("D:/FWI_future/fwi_intermediary/fwi_day_CanESM5_ssp245*.nc") fwi_list = [] for i in all_fwi: infile = xr.open_dataset(i, drop_variables=['TEMP_wDC_2014','ffmcPREV_2014', 'dcPREV_2014', 'dmcPREV_2014','SeasonActive_2014', 'DCf_2014', 'rw_2014', 'CounterSeasonActive_2014','ffmc', 'dc','dmc', 'isi', 'bui', 'TEMP', 'RH', 'RAIN', 'WIND']) yt = infile.sel(lon=slice(218.9931, 236.2107), lat=slice(60, 69.64794)) yt1 = yt.sel(time=slice('2020-01-01', '2060-12-31')) yt2 = yt1.sel(time=yt1.time.dt.month.isin([3, 4, 5, 6, 7, 8, 9])) fwi_list.extend(yt2)
单文件处理后的数据结构
处理后的单个yt2结构如下:
yt2 <xarray.Dataset> Size: 1MB Dimensions: (time: 8774, lat: 3, lon: 6, bnds: 2, days_wDC: 5) Coordinates: * time (time) object 70kB 2020-03-01 12:00:00 ... 2060-09-30 12:00:00 * lat (lat) float64 24B 62.79 65.58 68.37 * lon (lon) float64 48B 219.4 222.2 225.0 227.8 230.6 233.4 * days_wDC (days_wDC) <U5 100B 'day-2' 'day-1' 'day' 'day+1' 'day+2' Dimensions without coordinates: bnds Data variables: time_bnds (time, bnds) object 140kB ... lat_bnds (lat, bnds) float64 48B ... lon_bnds (lon, bnds) float64 96B ... fwi (time, lat, lon) float64 1MB ...
尝试过的方法及错误
- 原本想用rioxarray.merge,但该函数已弃用且无替代方案
- 尝试用netCDF4.Dataset写入:
报错信息:fin_dat = netCDF4.Dataset(fwi_list, 'w', format='NETCDF4')PermissionError: [Errno 13] Permission denied: "['time_bnds', 'lat_bnds', 'lon_bnds', 'fwi'...
解决步骤
1. 修正列表填充方式
代码中fwi_list.extend(yt2)会把Dataset的变量名作为字符串添加到列表,而非完整的Dataset对象,必须改成fwi_list.append(yt2),这样列表里才是一个个可合并的Dataset。
2. 用xarray合并Dataset列表
根据数据维度情况选择合并方式:
- 如果所有Dataset除time外维度一致,且time维度可拼接:用
xr.concat()merged_dataset = xr.concat(fwi_list, dim='time') - 如果Dataset存在不同变量或维度需要合并:用
xr.merge()merged_dataset = xr.merge(fwi_list)
3. 写入NetCDF文件
合并完成后直接用xarray内置方法写入,无需调用netCDF4.Dataset:
merged_dataset.to_netcdf("D:/FWI_future/fwi_intermediary/merged_fwi_ssp245.nc", format='NETCDF4')
完整修正代码
import glob import xarray as xr all_fwi = glob.glob("D:/FWI_future/fwi_intermediary/fwi_day_CanESM5_ssp245*.nc") fwi_list = [] for i in all_fwi: infile = xr.open_dataset(i, drop_variables=['TEMP_wDC_2014','ffmcPREV_2014', 'dcPREV_2014', 'dmcPREV_2014','SeasonActive_2014', 'DCf_2014', 'rw_2014', 'CounterSeasonActive_2014','ffmc', 'dc','dmc', 'isi', 'bui', 'TEMP', 'RH', 'RAIN', 'WIND']) yt = infile.sel(lon=slice(218.9931, 236.2107), lat=slice(60, 69.64794)) yt1 = yt.sel(time=slice('2020-01-01', '2060-12-31')) yt2 = yt1.sel(time=yt1.time.dt.month.isin([3, 4, 5, 6, 7, 8, 9])) # 修正:用append保存完整Dataset对象 fwi_list.append(yt2) # 合并Dataset列表(根据数据情况选concat或merge) merged_dataset = xr.concat(fwi_list, dim='time') # 写入NetCDF文件 merged_dataset.to_netcdf("D:/FWI_future/fwi_intermediary/merged_fwi_ssp245.nc", format='NETCDF4')
关键说明
extend(yt2)是错误操作,会破坏Dataset结构,必须用append()- xarray的合并函数已处理NetCDF格式兼容,无需手动操作netCDF4库
- 若合并出现维度冲突,可添加
compat='override'参数处理重复变量,如xr.concat(fwi_list, dim='time', compat='override')
内容的提问来源于stack exchange,提问作者user11384727
相关产品推荐
相关产品推荐

