【问题标题】:xarray computing monthly mean from multiple year netcdfxarray 计算来自多年 netcdf 的月平均值
【发布时间】:2021-03-28 15:44:11
【问题描述】:

我有一个来自 ERA5 的 2m 温度 netcdf 文件,该文件从 2000 年到 2019 年 04 到 10 个月,总共有 13680 个时间步长和 61x161 经纬度维度。我想分别计算每年所有每日时间步长的月平均值。例如,我们将获得 2000 年 4 月、2000 年 5 月等数据的月平均值。我用 xarray resample 尝试了以下代码,但出现了两个问题。

  1. 出于某种原因,平均值似乎多年来一直都是平均值。
  2. resample 函数会创建月份 01、02、03、11 和 12,尽管它没有数据!

这就是我要说的:

import xarray as xr
ds = xr.open_dataset(netcdf)
monthly_data=ds.resample(time='1M').mean()

我们可以查看显示每月时间步长的时间戳,包括不相关的月份。

print(np.array(monthly_data.time))
array(['2000-04-30T00:00:00.000000000', '2000-05-31T00:00:00.000000000',
       '2000-06-30T00:00:00.000000000', '2000-07-31T00:00:00.000000000',
       '2000-08-31T00:00:00.000000000', '2000-09-30T00:00:00.000000000',
       '2000-10-31T00:00:00.000000000', '2000-11-30T00:00:00.000000000',
       '2000-12-31T00:00:00.000000000', '2001-01-31T00:00:00.000000000',

为了验证温度的内容,我把数据变成了数据框。

temp_ar = np.array(monthly_data.t2m)    
print(pd.DataFrame(temp_ar[0,:,:]).head())
          0           1           2    ...         158         159         160
0  270.940613  270.911652  270.926727  ...         NaN         NaN         NaN
1  271.294952  271.256744  271.250946  ...  272.948608  272.974731  272.998535
2  271.416779  271.457214  271.483459  ...  273.123169  273.079285  273.058563
3  271.848755  271.791382  271.784058  ...         NaN  273.264038         NaN
4  272.226837  272.144928  272.123016  ...         NaN         NaN         NaN

print(pd.DataFrame(temp_ar[1,:,:]).head())
   0    1    2    3    4    5    6    ...  154  155  156  157  158  159  160
0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  ...  NaN  NaN  NaN  NaN  NaN  NaN  NaN
1  NaN  NaN  NaN  NaN  NaN  NaN  NaN  ...  NaN  NaN  NaN  NaN  NaN  NaN  NaN
2  NaN  NaN  NaN  NaN  NaN  NaN  NaN  ...  NaN  NaN  NaN  NaN  NaN  NaN  NaN
3  NaN  NaN  NaN  NaN  NaN  NaN  NaN  ...  NaN  NaN  NaN  NaN  NaN  NaN  NaN
4  NaN  NaN  NaN  NaN  NaN  NaN  NaN  ...  NaN  NaN  NaN  NaN  NaN  NaN  NaN

第二个数组(对应于 2000 年 05 月)不应该有 nans,但是对于所有其他时间步长(由于某种原因最后一个除外),它确实如此,并且它像这样。有人知道为什么会这样吗?

这是原始数据集

print(ds)
<xarray.Dataset>
Dimensions:    (latitude: 61, longitude: 161, time: 13680)
Coordinates:
  * longitude  (longitude) float32 -80.0 -79.9 -79.8 -79.7 ... -64.2 -64.1 -64.0
  * latitude   (latitude) float32 50.0 49.9 49.8 49.7 ... 44.3 44.2 44.1 44.0
  * time       (time) datetime64[ns] 2000-04-01 ... 2018-10-30T23:00:00
Data variables:
    t2m        (time, latitude, longitude) float32 ...
Attributes:
    Conventions:  CF-1.6
    history:      2020-12-07 03:50:31 GMT by grib_to_netcdf-2.16.0: /opt/ecmw...

任何帮助都可以。也许我应该尝试其他方法? 干杯!

【问题讨论】:

标签: python netcdf python-xarray


【解决方案1】:

我认为任何简单的方法都是使用groupby method

例子:

da = xr.DataArray(
    np.linspace(0, 1673, num=1674),
    coords=[pd.date_range("1/1/2000", "31/07/2004", freq="D")],
    dims="time",
)
da

输出:

<xarray.DataArray (time: 1674)>
array([0.000e+00, 1.000e+00, 2.000e+00, ..., 1.671e+03, 1.672e+03, 1.673e+03])
Coordinates:
  * time     (time) datetime64[ns] 2000-01-01 2000-01-02 ... 2004-07-31

对于年平均你可以这样做:

da.groupby('time.year').mean()

输出:

<xarray.DataArray (year: 5)>
array([ 182.5,  548. ,  913. , 1278. , 1567. ])
Coordinates:
  * year     (year) int64 2000 2001 2002 2003 2004

对于不同年份的每个月的平均值,您可以创建一个多索引:

year_month_idx = pd.MultiIndex.from_arrays([da['time.year'], da['time.month']])
da.coords['year_month'] = ('time', year_month_idx)
da.groupby('year_month').mean()

输出:

<xarray.DataArray (year_month: 55)>
array([  15. ,   45. ,   75. ,  105.5,  136. ,  166.5,  197. ,  228. ,  258.5,
        289. ,  319.5,  350. ,  381. ,  410.5,  440. ,  470.5,  501. ,  531.5,
        562. ,  593. ,  623.5,  654. ,  684.5,  715. ,  746. ,  775.5,  805. ,
        835.5,  866. ,  896.5,  927. ,  958. ,  988.5, 1019. , 1049.5, 1080. ,
       1111. , 1140.5, 1170. , 1200.5, 1231. , 1261.5, 1292. , 1323. , 1353.5,
       1384. , 1414.5, 1445. , 1476. , 1506. , 1536. , 1566.5, 1597. , 1627.5,
       1658. ])
Coordinates:
 * year_month          (year_month) MultiIndex
 * year_month_level_0  (year_month) int64 2000 2000 2000 ... 2002 2002 2002
 * year_month_level_1  (year_month) int64 1 2 3 4 5 6 7 8 ... 11 12 1 2 3 4 5 6

【讨论】:

  • 感谢这完美的工作!在我的情况下,我在尝试转换为多索引时遇到 TypeError: unhashable type: 'DataArray',但为了解决这个问题,我只是将时间转换为 numpy 数组,使其看起来像这样:pd.MultiIndex.from_arrays([np .array(da['time.year']), np.array(da['time.month'])])
  • 我遇到了同样的问题;在这里提到它的荣誉。另一方面,添加 .values 会将 DataArray 转换为 numpy 数组。表达式为:pd.MultiIndex.from_arrays([da['time.year'].values, da['time.month'].values]) 文档:xarray.pydata.org/en/stable/generated/…
猜你喜欢
  • 2019-10-09
  • 2020-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-12
  • 2018-08-08
  • 2018-01-29
相关资源
最近更新 更多