如何沿时间轴合并10个Ichthyop输出的NetCDF文件并保留属性
用Xarray合并Ichthyop拉格朗日模拟NetCDF文件
解决方案代码
import xarray as xr import glob import numpy as np from datetime import datetime # 按年份顺序获取所有目标NetCDF文件(根据实际文件名调整匹配规则) file_paths = sorted(glob.glob("ichthyop_201[3-9].nc") + glob.glob("ichthyop_202[0-2].nc")) processed_datasets = [] all_release_events = [] for file_path in file_paths: # 读取单个数据集 ds = xr.open_dataset(file_path) # 从属性提取初始时间并解析释放年份 initial_time_str = ds.attrs["app.time.initial_time"] release_year = datetime.fromisoformat(initial_time_str).year # 为每个漂流者添加释放年份变量 ds["release_year"] = xr.DataArray( np.full(ds.drifter.size, release_year), dims=["drifter"], attrs={"description": "Year of drifter release"} ) # 收集当前文件的释放调度事件 current_events = ds.attrs.get("release.schedule.events", []) if isinstance(current_events, list): all_release_events.extend(current_events) else: all_release_events.append(current_events) processed_datasets.append(ds) # 合并所有数据集(沿drifter维度,解决索引重复问题) final_dataset = xr.concat(processed_datasets, dim="drifter", combine_attrs="drop_conflicts") # 写入合并后的释放调度事件属性 final_dataset.attrs["release.schedule.events"] = all_release_events # 可选:保留所有文件的初始时间记录 final_dataset.attrs["app.time.all_initial_times"] = [ds.attrs["app.time.initial_time"] for ds in processed_datasets] # 保存结果文件 final_dataset.to_netcdf("merged_mediterranean_drifters_2013-2022.nc")
关键步骤说明
- 提取释放年份:通过解析
app.time.initial_time属性获取年份,确保每个漂流者的来源年份可追溯。 - 添加release_year变量:给每个数据集的
drifter维度绑定年份变量,彻底解决不同文件间漂流者索引重复的问题。 - 合并释放事件属性:将所有文件的
release.schedule.events收集后合并,保留完整的释放调度信息。 - 数据集合并:使用
xr.concat沿drifter维度合并,combine_attrs="drop_conflicts"会自动移除不同文件间冲突的属性(如单个文件的app.time.initial_time),同时保留共同属性。
适配调整建议
- 如果
app.time.initial_time的格式不是ISO标准格式,需修改年份解析逻辑(比如按特定分隔符拆分字符串)。 - 若
release.schedule.events是字符串格式而非列表,可将合并逻辑改为用换行符拼接:"\n".join(all_release_events)。 - 若需沿时间轴合并(而非漂流者维度),需确认所有文件的
time维度是连续的,此时可将concat的dim参数改为"time",但需确保漂流者索引的唯一性(通过release_year区分)。
内容的提问来源于stack exchange,提问作者Yotam Ben Saadon
相关产品推荐
相关产品推荐

