【问题标题】:quantile method on groupby of xarray datasetxarray数据集groupby的分位数方法
【发布时间】:2018-04-16 13:04:49
【问题描述】:

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

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

<xarray.Dataset>
Dimensions:        (lat: 26, lon: 71, time: 456)
Coordinates:
  * lat            (lat) float32 25.0 26.0 27.0 28.0 29.0 30.0 31.0 32.0 ...
  * lon            (lon) float32 -130.0 -129.0 -128.0 -127.0 -126.0 -125.0 ...
  * time           (time) datetime64[ns] 1979-01-31 1979-02-28 1979-03-31 ...
Data variables:
    var1         (time, lat, lon) float32 nan nan nan nan nan nan nan nan ...
    var2         (time, lat, lon) float32 nan nan nan nan nan nan nan nan ...
    var3         (time, lat, lon) float32 nan nan nan nan nan nan nan nan ...
    ......

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

ds.groupby(‘time.month’).mean(dim=‘time’)

但如果我尝试

ds.groupby(‘time.month’).quantile(0.75, dim=‘time’)

我明白了

AttributeError: 'DatasetGroupBy' object has no attribute 'quantile'

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

其实我尝试了以下方法:

df_ds = xr.Dataset.to_dataframe(ds)
df_ds = df_ds.reset_index()
df_ds = df_ds.set_index('time')
df_ds.groupby(pd.TimeGrouper(freq='M')).quantile(0.75)

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

那么,xarray 能做到吗?也许使用一些 apply/lambda 组合?

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

Data_clim_monthly_75g = ds.where(iok_conus_xarray).groupby('time.month')
Data_clim_monthly_75 = ds.where(iok_conus_xarray).groupby('time.month').mean(dim='time')

v1 = Data_clim_monthly_75['var1'].values
v2 = Data_clim_monthly_75['var2'].values
v3 = Data_clim_monthly_75['var3'].values
v4 = Data_clim_monthly_75['var4'].values
for k, gp in Data_clim_monthly_75g:
    v1[k-1] =  np.nanpercentile(gp['var1'].values,q=75,axis=0)
    v2[k-1] =  np.nanpercentile(gp['var2'].values,q=75,axis=0)
    v3[k-1] =  np.nanpercentile(gp['var3'].values,q=75,axis=0)
    v4[k-1] =  np.nanpercentile(gp['var4'].values,q=75,axis=0)
Data_clim_monthly_75['var1'] = (('month','lat','lon'),v1)    
Data_clim_monthly_75['var2'] = (('month','lat','lon'),v2)    
Data_clim_monthly_75['var3'] = (('month','lat','lon'),v3)    
Data_clim_monthly_75['var4'] = (('month','lat','lon'),v4)    

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

【问题讨论】:

    标签: pandas-groupby quantile python-xarray


    【解决方案1】:

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

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

    编辑:from xarray version 0.12.2 onwards GroupBy 对象确实具有您正在寻找的 GroupBy.quantile 方法:

    ds.groupby(‘time.month’).quantile(q=0.75, dim=‘time’)
    

    【讨论】:

    • 太棒了 - 确实比我的解决方案有效且速度更快。
    • @jhamman 如果我有一个多年来按小时计算的 xarray 并且我会返回一天的百分位数,该怎么办?像 ds.resample(time='24H').reduce(np.nanpercentile, dim='time', q=0.90) 这样的东西真的很耗时
    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 2017-03-31
    • 2020-07-02
    • 2023-04-08
    • 2021-06-14
    • 2018-04-01
    相关资源
    最近更新 更多