【问题标题】:How turn this monthly xarray dataset into an annual mean without resampling?如何在不重新采样的情况下将此月度 xarray 数据集转换为年平均值?
【发布时间】:2017-11-18 00:37:17
【问题描述】:

我有一个使用 open_datasetdecode_times=False 从服务器读取的月平均表面温度 xarray,因为 xarray 不理解日历类型。

经过一些操作,我得到了一个包含表面温度 ('ts') 和时间 ('T') 的数据集 my_dataset

<xarray.Dataset>
Dimensions:  (T: 1800)
Coordinates:
  * T        (T) float32 0.5 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5 10.5 11.5 ...
Data variables:
    ts       (T) float64 246.6 247.9 250.7 260.1 271.9 281.1 283.3 280.5 ...

'T'具有以下属性:

Attributes:
    pointwidth:  1.0
    calendar:    360
    gridtype:    0
    units:       months since 0300-01-01

我想获取这个月度数据并计算年平均值,但由于 T 坐标不是日期时间,我无法使用 xarray.Dataset.resample。现在,我只是转换为一个 numpy 数组,但我想要一种方法来保留 xarray 数据集。

我目前的基本方法:

temps = np.mean(np.array(my_dataset['ts']).reshape(-1,12),axis=1)
years = np.array(my_dataset['T'])/12

感谢任何帮助,即使最好的方法是重新定义时间坐标以使用重采样。

编辑: 询问如何创建 xarray,它是通过以下方式完成的:

import numpy as np
import matplotlib.pyplot as plt
import xarray as xr

filename = 'http://strega.ldeo.columbia.edu:81/CMIP5/.byScenario/.abrupt4xCO2/.atmos/.mon/.ts/ACCESS1-0/r1i1p1/.ts/dods'
ds = xr.open_dataset(filename,decode_times=False)

zonal_mean = ds.mean(dim='lon')
arctic_only = zonal.where(zonal['lat'] >= 60).dropna('lat')
weights = np.cos(np.deg2rad(arctic['lat']))/np.sum(np.cos(np.deg2rad(arctic['lat'])))
my_dataset = (arctic_only * weights).sum(dim='lat')

【问题讨论】:

  • 你试过像ts analysis那样使用decode_cf
  • @sharatpc 谢谢你的建议,但我无法使用decode_cf 没有得到:ValueError: units must be one of 'seconds', 'minutes', 'hours' or 'days' (or singular version of these), got 'months' 即使将日历更改为 360_day 后
  • 你能发布数据集是如何创建的,而不是输出吗?使其易于复制。
  • @sharatpc 已编辑以反映数据集的创建
  • url 或者我猜测需要 Geo JSON。至少要使用前几个坐标。

标签: python numpy python-datetime python-xarray


【解决方案1】:

这是一个非常常见的问题,尤其是对于来自 INGRID 的数据集。 xarray 无法解码其单位为“自...以来的月份”的日期的原因是由于底层的 netcdf4-python 库拒绝解析此类日期。 netcdf4-python github issue

对此进行了讨论

诸如“月”之类的时间单位的问题在于它们的定义不明确。与天、小时等相比,一个月的长度取决于所使用的日历,甚至在不同月份之间也会有所不同。

INGRID 遗憾地拒绝接受这一事实,并继续使用“月”作为其默认单位,尽管存在歧义。所以现在INGRID和xarray / python-netcdf4之间存在令人沮丧的不兼容。

无论如何,这是一个无需离开 xarray 即可完成您想要的事情的 hack

# create new coordinates for month and year
ds.coords['month'] = np.ceil(ds['T'] % 12).astype('int') 
ds.coords['year'] = (ds['T'] // 12).astype('int')
# calculate monthly climatology
ds_clim = ds.groupby('month').mean(dim='T')
# calculate annual mean
ds_am = ds.groupby('year').mean(dim='T')

【讨论】:

  • @LonelyHeartsClub - 这对你有用吗?如果可以,你能接受我的回答吗?
  • 我现在就试试,我周末工作,所以很遗憾我还没有机会尝试。
  • 这很好用。再次感谢您的帮助。我接受了你的回答。
猜你喜欢
  • 2019-04-30
  • 1970-01-01
  • 1970-01-01
  • 2017-01-23
  • 2019-07-18
  • 2021-05-17
  • 1970-01-01
  • 2021-10-23
  • 2015-12-22
相关资源
最近更新 更多