我正在尝试用最接近的值填充二维 xarray(纬度、经度)中的 NaN。
我有以下示例代码,其中应用了陆地-海洋掩模。然后我想用它们各自最接近的陆地点值填充海洋点。
我知道 bfill 和 ffill 会按照这些思路做一些事情,但不完全是我想要的。
理想情况下,所有海洋点应在最后填满。
有什么想法吗?
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import regionmask
def mask_ocean(arr, maskValue=np.nan):
land = regionmask.defined_regions.natural_earth.land_110.mask(arr)
masked = xr.where(land==0, arr, maskValue)
return masked
# Create sample data
lon = np.arange(129.4, 153.75+0.05, 0.25)
lat = np.arange(-43.75, -10.1+0.05, 0.25)
data = 10 * np.random.rand(len(lat), len(lon))
ds = xr.Dataset({"DC": (["lat", "lon"], data)}, coords={"lon": lon,"lat": lat})
#< Mask ocean
ds = mask_ocean(ds)
#< Plotting
fig, axes = plt.subplots(nrows=1, ncols=1, subplot_kw={'projection': ccrs.PlateCarree()}) # Use PlateCarree projection
ds['DC'].plot(ax=axes, cmap='Spectral_r', add_colorbar=True, extend='both')
axes.coastlines() # Add coastlines
plt.show()
这是我多次遇到的问题,xarray 没有 有一个适当的方法可以轻松处理这个问题。
一种可能的快速解决方案是使用 CDO
cdo setmisstonn inFile.nc outFile.nc
这基本上就是你想要的。你也可以有一条蟒蛇 cdo 接口 (py-cdo)
outds = cdo.setmisstonn(input=ds,returnXDataset=True)
您可以使用@orlp的这个答案中所示的方法。 对于称为
xarray.DataArray
的 da
(在本问题中,它将是 da = ds.DC
),其工作原理如下:
from scipy.interpolate import NearestNDInterpolator
indices = np.where(np.isfinite(da))
interp = NearestNDInterpolator(np.transpose(indices), da.data[indices])
da[...] = interp(*np.indices(da.shape))
最后一行用最接近的有限值替换
da
中的非有限 (NaN) 值。
然而,“最近的”在这里由索引/网格点的数量定义。
这并不总是等于地球上物理距离测量的最近点。
当
da
的维度超过 2 维时,此解决方案也适用(我也用 3 维进行了测试)。