From fe700d73600ac2a8059cabae15dbb01a1bbe94e5 Mon Sep 17 00:00:00 2001 From: Stephan Hoyer Date: Tue, 2 Oct 2018 17:35:29 +0200 Subject: [PATCH 1/2] WIP: sketch of resample support for CFTimeIndex Example usage: >>> import xarray >>> times = xarray.cftime_range('2000', periods=30, freq='MS') >>> da = xarray.DataArray(range(30), [('time', times)]) >>> da.resample(time='1AS').mean() array([ 5.5, 17.5, 26.5]) Coordinates: * time (time) object 2001-01-01 00:00:00 ... 2003-01-01 00:00:00 --- xarray/core/common.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/xarray/core/common.py b/xarray/core/common.py index 41e4fec2982..ad65d7dcf18 100644 --- a/xarray/core/common.py +++ b/xarray/core/common.py @@ -656,6 +656,7 @@ def resample(self, freq=None, dim=None, how=None, skipna=None, """ # TODO support non-string indexer after removing the old API. + from ..coding.cftimeindex import CFTimeIndex from .dataarray import DataArray from .resample import RESAMPLE_DIM @@ -679,12 +680,20 @@ def resample(self, freq=None, dim=None, how=None, skipna=None, if isinstance(dim, basestring): dim_name = dim - dim = self[dim] + dim_array = self[dim] else: raise TypeError("Dimension name should be a string; " "was passed %r" % dim) - group = DataArray(dim, [(dim.dims, dim)], name=RESAMPLE_DIM) - grouper = pd.Grouper(freq=freq, closed=closed, label=label, base=base) + group = DataArray(dim_array, [(dim_array.dims, dim_array)], + name=RESAMPLE_DIM) + + if isinstance(self.indexes[dim], CFTimeIndex): + # TODO: handle closed, label and base arguments, and the case where + # frequency is specified without an integer count. + grouper = self.indexes[dim].shift(n=int(freq[0]), freq=freq[1:]) + else: + grouper = pd.Grouper( + freq=freq, closed=closed, label=label, base=base) resampler = self._resample_cls(self, group=group, dim=dim_name, grouper=grouper, resample_dim=RESAMPLE_DIM) From b488148a92c033bb6d5975f24035f9566a12ef11 Mon Sep 17 00:00:00 2001 From: Stephan Hoyer Date: Wed, 3 Oct 2018 17:18:21 +0200 Subject: [PATCH 2/2] New implementation using cftime_range --- xarray/core/common.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/xarray/core/common.py b/xarray/core/common.py index ad65d7dcf18..7c811182816 100644 --- a/xarray/core/common.py +++ b/xarray/core/common.py @@ -656,6 +656,7 @@ def resample(self, freq=None, dim=None, how=None, skipna=None, """ # TODO support non-string indexer after removing the old API. + from ..coding.cftime_offsets import cftime_range from ..coding.cftimeindex import CFTimeIndex from .dataarray import DataArray from .resample import RESAMPLE_DIM @@ -690,7 +691,11 @@ def resample(self, freq=None, dim=None, how=None, skipna=None, if isinstance(self.indexes[dim], CFTimeIndex): # TODO: handle closed, label and base arguments, and the case where # frequency is specified without an integer count. - grouper = self.indexes[dim].shift(n=int(freq[0]), freq=freq[1:]) + times = self.indexes[dim] + resampled_times = cftime_range( + start=times[0], end=times[-1], freq=freq) + grouper = (pd.Series(resampled_times, index=resampled_times) + .reindex(times, method='pad')) else: grouper = pd.Grouper( freq=freq, closed=closed, label=label, base=base)