2 回答

TA貢獻1797條經驗 獲得超6個贊
使用形狀為 (3, 3, 1) 的內核代替 (3, 3) 怎么樣?
kernel2d = np.ones((3, 3))
conv2d = lambda x: convolve(x, kernel2d, mode="wrap")
result2d = xr.apply_ufunc(conv2d, da[:, :, 0])
kernel3d = np.ones((3, 3, 1))
conv3d = lambda x: convolve(x, kernel3d, mode="wrap")
result3d = xr.apply_ufunc(conv3d, da)
(result2d == result3d[:, :, 0]).all() # -> True
另一種選擇是在 中使用矢量化邏輯xr.apply_ufunc,這可能更接近您嘗試執行的操作
kernel = np.ones((3, 3))
conv = lambda x: convolve(x, kernel, mode="wrap")
result = xr.apply_ufunc(conv, da, input_core_dims=[['x', 'y']],
output_core_dims=[['x', 'y']],
vectorize=True)
(result2d == result.transpose('x', 'y', 'z')).all() # --> True
此選項只是為了方便而準備的,因此它可能比計算矢量化的第一個要慢得多。

TA貢獻1807條經驗 獲得超9個贊
我想出的一個可能的答案是手動執行此操作:
def conv_rx(da, axis="z"):
planes = [ xr.apply_ufunc(conv1, da.sel(z=z)) for z in da.z ]
new = xr.concat(planes, dim=axis)
return new.transpose(*da.dims)
這會產生正確的結果。但是,我對此不太滿意,因為它不優雅而且速度很慢。
添加回答
舉報