xarray数据集groupby的分位数方法

cla*_*ude 4 quantile python-xarray pandas-groupby

我有一个经典的 xarray 数据集。这些是月度数据(38 年的月度数据)。

\n\n

我有兴趣分别计算每个月的分位数值。

\n\n
<xarray.Dataset>\nDimensions:        (lat: 26, lon: 71, time: 456)\nCoordinates:\n  * lat            (lat) float32 25.0 26.0 27.0 28.0 29.0 30.0 31.0 32.0 ...\n  * lon            (lon) float32 -130.0 -129.0 -128.0 -127.0 -126.0 -125.0 ...\n  * time           (time) datetime64[ns] 1979-01-31 1979-02-28 1979-03-31 ...\nData variables:\n    var1         (time, lat, lon) float32 nan nan nan nan nan nan nan nan ...\n    var2         (time, lat, lon) float32 nan nan nan nan nan nan nan nan ...\n    var3         (time, lat, lon) float32 nan nan nan nan nan nan nan nan ...\n    ......\n
Run Code Online (Sandbox Code Playgroud)\n\n

例如,如果我想要每个月的平均值,我使用:

\n\n
ds.groupby(\xe2\x80\x98time.month\xe2\x80\x99).mean(dim=\xe2\x80\x98time\xe2\x80\x99)\n
Run Code Online (Sandbox Code Playgroud)\n\n

但如果我尝试

\n\n
ds.groupby(\xe2\x80\x98time.month\xe2\x80\x99).quantile(0.75, dim=\xe2\x80\x98time\xe2\x80\x99)\n
Run Code Online (Sandbox Code Playgroud)\n\n

我明白了

\n\n
AttributeError: 'DatasetGroupBy' object has no attribute 'quantile'\n
Run Code Online (Sandbox Code Playgroud)\n\n

然而,根据 Pandas 文档,分位数适用于 groupby 对象。

\n\n

事实上,我尝试了以下方法:

\n\n
df_ds = xr.Dataset.to_dataframe(ds)\ndf_ds = df_ds.reset_index()\ndf_ds = df_ds.set_index('time')\ndf_ds.groupby(pd.TimeGrouper(freq='M')).quantile(0.75)\n
Run Code Online (Sandbox Code Playgroud)\n\n

它有效;当然,这是一个更简单的例子,因为我只有一个索引,事实上,如果我不将reset_index/set_index只设置为一个索引,我会从pandas收到一个错误,它无法处理多索引。

\n\n

那么,xarray可以吗?也许使用一些 apply/lambda 组合?

\n\n

我找到了一种非常不优雅的方法来解决它。这是可行的,因为我有 4 个变量(我可以查看变量名称,但我不在这里):

\n\n
Data_clim_monthly_75g = ds.where(iok_conus_xarray).groupby('time.month')\nData_clim_monthly_75 = ds.where(iok_conus_xarray).groupby('time.month').mean(dim='time')\n\nv1 = Data_clim_monthly_75['var1'].values\nv2 = Data_clim_monthly_75['var2'].values\nv3 = Data_clim_monthly_75['var3'].values\nv4 = Data_clim_monthly_75['var4'].values\nfor k, gp in Data_clim_monthly_75g:\n    v1[k-1] =  np.nanpercentile(gp['var1'].values,q=75,axis=0)\n    v2[k-1] =  np.nanpercentile(gp['var2'].values,q=75,axis=0)\n    v3[k-1] =  np.nanpercentile(gp['var3'].values,q=75,axis=0)\n    v4[k-1] =  np.nanpercentile(gp['var4'].values,q=75,axis=0)\nData_clim_monthly_75['var1'] = (('month','lat','lon'),v1)    \nData_clim_monthly_75['var2'] = (('month','lat','lon'),v2)    \nData_clim_monthly_75['var3'] = (('month','lat','lon'),v3)    \nData_clim_monthly_75['var4'] = (('month','lat','lon'),v4)    \n
Run Code Online (Sandbox Code Playgroud)\n\n

我基本上是围绕 xarray 工作的。我仍然喜欢 xarray 中的解决方案。

\n

jha*_*man 5

我们还没有将 quantile 方法添加到 groupby 对象中。但是,您可以使用该reduce方法将任意归约函数应用于每个组。在下面的示例中,我应用np.nanpercentile于每个组。

\n\n
In [21]: ds\nOut[21]:\n<xarray.Dataset>\nDimensions:  (lat: 71, lon: 26, time: 456)\nCoordinates:\n  * time     (time) datetime64[ns] 1979-01-31 1979-02-28 1979-03-31 ...\nDimensions without coordinates: lat, lon\nData variables:\n    var1     (time, lon, lat) float64 0.4286 0.4032 0.2178 0.7652 0.8108 ...\n    var2     (time, lon, lat) float64 0.8259 0.3625 0.6556 0.7403 0.2381 ...\n\nIn [22]: ds.groupby(\'time.month\').reduce(np.nanpercentile, dim=\'time\', q=0.75)\nOut[22]:\n<xarray.Dataset>\nDimensions:  (lat: 71, lon: 26, month: 12)\nCoordinates:\n  * month    (month) int64 1 2 3 4 5 6 7 8 9 10 11 12\nDimensions without coordinates: lat, lon\nData variables:\n    var1     (month, lon, lat) float64 0.04153 0.03099 0.07881 0.01749 ...\n    var2     (month, lon, lat) float64 0.03518 0.06896 0.01287 0.025 0.01536 ...\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

编辑:从 xarray 版本 0.12.2 开始, GroupBy 对象确实具有GroupBy.quantile您正在寻找的

\n\n
ds.groupby(\xe2\x80\x98time.month\xe2\x80\x99).quantile(q=0.75, dim=\xe2\x80\x98time\xe2\x80\x99)\n
Run Code Online (Sandbox Code Playgroud)\n