我收集了一组ERA5 netcdf文件,其中包含每小时的气温数据,这些数据跨越热带东太平洋地区大约40年的时间。在jupyter笔记本中,我想在合并的数据集上运行一个带通过滤器,但是我总是遇到与内存分配有关的初始错误。我使用xarray.open_mfdataset(list_of_files)读取文件,但当我试图加载数据集时,会得到以下错误:
Unable to allocate X GiB for an array with shape (d1, d2, d3, d4) and data type float32在jupyter中,是否有解决方案或最佳实践来操作这样的大型数据集?
带通滤波器的完整代码是:我一直想将带通滤波器应用到东太平洋上的一个大域上,大约40年来来自ERA5的数据。守则如下:
# Grab dataset
var = 't'
files = glob.glob(os.path.join(parent_dir, 'era5_' + var + '_daily.nc'))
files.sort()
# Read files into a dask array
ds = xr.open_mfdataset(files)
# Limit study region
lon_min = -140
lon_max = -80
lat_min = -10
lat_max = 10
ds = ds.sel(latitude = slice(lat_max, lat_min), longitude = slice(lon_min, lon_max))
# Now, load the data from the original dask array
da_T = ds.T.load()
# High pass filter (remove singal on the seasonal and longer timescales)
import xrft
freq_threshold = (1/90) * (1/24) * (1/3600) # 90-day frequency threshold
def high_pass_filter(da, dim, thres):
ft = xrft.fft(da, dim=dim, true_phase=True, true_amplitude=True)
ft_new = ft.where(ft.freq_time > thres, other = 0)
ft.close()
da_new = xrft.ifft(ft_new, dim = 'freq_time', true_phase=True, true_amplitude=True)
da_new = da_new + np.tile(da.mean('time'), (da_T.time.shape[0],1,1,1))
ft_new.close()
return da_new.real
da_new = high_pass_filter(da_T, 'time', freq_threshold)
# Save filtered dataset
da_new.real.to_netcdf(os.path.join(outdir, 'era5_T.nc')) 发布于 2022-08-01 22:18:46
当你这样做的时候
# Now, load the data from the original dask array
da_T = ds.T.load()您正在将数据集的"T"变量中的所有数据一次性加载到内存中。据推测,此变量的大小要大于系统上可用的RAM数量。
这一行还存在另一个问题:da.load()就地加载并返回修改后的对象。所以单靠ds.T.load()就足够了。您也可以使用da_T = ds.T.compute()代替。
您可以试着使用dask逐个执行分析。您希望在加载/计算ds对象之前确保您的对象包含块dask数组对象。
然后,您需要像您正在做的那样使用xarray方法/ xrft包指定您的分析,但只在最后调用.compute()。这应该是一次又一次的分析。
我建议阅读关于如何在一起使用dask + xarray的文章,以使它能够顺利运行。
https://stackoverflow.com/questions/73085364
复制相似问题