Xarray中Dask数组滚动均值操作出现数据与坐标尺寸冲突问题
解决xarray中Dask数组滚动均值的维度冲突问题
咱们先来拆解你碰到的两个问题:
第一个错误:块大小小于窗口重叠深度
你最初遇到的ValueError: The overlapping depth 30 is larger than your smallest chunk size 1,这事儿原因其实挺直白的:滚动窗口计算需要跨块访问数据,但你的dayofyear维度被拆成了大小为1的块,窗口大小31意味着每个计算要拉取30个相邻块的数据,Dask搞不定这种跨块依赖,所以要求你重新分块成更大的块——你后来用chunk({'dayofyear': 366})把整个维度做成一个块,已经解决了这个问题。
第二个错误:数据与坐标维度不匹配
当你用center=True跑滚动均值时,xarray会自动丢掉那些没法被完整窗口覆盖的边缘数据:
- 窗口大小是31,中心模式下,前15个和后15个数据点凑不齐完整窗口,所以结果的长度变成了
366 - 2*15 = 351。
对于普通的numpy数组,xarray会自动裁剪对应的坐标来匹配结果长度,但Dask数组是延迟计算的,xarray没法提前预判结果的坐标形状,所以直接保留了原始的366个dayofyear坐标,这下就出现了数据长度(351)和坐标长度(366)不匹配的冲突。
解决方案:手动对齐坐标
咱们可以在算完滚动均值后,手动把dayofyear坐标裁剪到和结果匹配的长度:
import xarray as xr # 加载数据(和你的代码一致) remote_data = xr.open_dataarray('http://iridl.ldeo.columbia.edu/SOURCES/.Models/SubX/.RSMAS/.CCSM4/.hindcast/.zg/dods', chunks={'L': 1, 'S': 1}) da = remote_data.isel(P=0,L=0,M=0,X=0,Y=0) da_day_clim = da.groupby('S.dayofyear').mean('S') # 重新分块为完整的dayofyear维度 da_day_clim2 = da_day_clim.chunk({'dayofyear': 366}) # 定义滚动窗口参数 window_size = 31 half_window = window_size // 2 # 15 # 计算滚动均值 da_day_clim_smooth = da_day_clim2.rolling(dayofyear=window_size, center=True).mean() # 手动裁剪坐标,匹配结果长度 da_day_clim_smooth = da_day_clim_smooth.assign_coords( dayofyear=da_day_clim.dayofyear[half_window:-half_window] ) # 现在可以正常查看或计算结果了 print(da_day_clim_smooth)
另一种简单方案:先转成numpy数组(数据量不大时适用)
如果你的数据量没那么大,能塞进内存,可以先调用compute()把Dask数组转成numpy数组,这样xarray会自动帮你处理坐标的裁剪:
da_day_clim_np = da_day_clim.compute() da_day_clim_smooth = da_day_clim_np.rolling(dayofyear=31, center=True).mean()
这种方法更省事,但要注意——如果数据太大,加载到内存里会撑爆内存,所以只适合小数据集。
内容的提问来源于stack exchange,提问作者Ray Bell
相关产品推荐
相关产品推荐

