从 Python 中的多个 xarray.Datasets 中屏蔽 NaN

问题描述

如何从具有相同形状的多个 xarray 数据集中屏蔽 NaN,以便在没有 NaN 的情况下保留通用形状?

import numpy as np
import pandas as pd
import xarray as xr

arrays = [np.array(["bar","bar","baz","foo","qux","qux"]),np.array(["one","two","one","two"])]
df1 = pd.DataFrame(np.random.randn(8,4),index=arrays)
df1.iloc[[2,3,2],:] = np.nan
ds1 = df1.to_xarray()

arrays = [np.array(["bar","two"])]
df2 = pd.DataFrame(np.random.randn(8,index=arrays)
df2.iloc[[1,4,1],:] = np.nan
ds2 = df2.to_xarray()

arrays = [np.array(["bar","two"])]
df3 = pd.DataFrame(np.random.randn(8,index=arrays)
df3.iloc[[2,1,:] = np.nan
ds3 = df3.to_xarray()

在上面的示例数据集中,我为不同行和列的每个数据集制作了 NaN。我想屏蔽任何数据集具有 NaN 的行。那么预期的结果将是没有从顶部开始的第二行~第五行的数据帧,如下所示:

df3.iloc[[0,5,6,7],:]

虽然为了方便和可视化,我用 pd.dataframe 来描述,但我想在 xarray.Dataset 结构中做到这一点。我的试验是使用 xr.dataset.where() 之类的 ...

ds1_masked = ds1.where(ds1 != np.nan and ds2 != np.nan and ds3 != np.nan,drop=True)

这不起作用(创建了一个没有任何变量的数据集)。

解决方法

这是我这边的解决方案:

mask = 1-(np.isnan(ds1.0.values) | np.isnan(ds2.0.values) | np.isnan(ds3.0.values))
ds1_mask_nan = ds1.where(mask,np.nan)    
ds1_mask_out = ds1_mask_nan.where(1-np.isnan(ds1_mask_nan[0]),drop=True)