@@ -72,17 +72,12 @@ def __init__(self, freq='Min', closed=None, label=None, how='mean',
7272 self .base = base
7373
7474 def resample (self , obj ):
75- axis = obj ._get_axis (self .axis )
75+ ax = obj ._get_axis (self .axis )
7676
77- if not axis .is_monotonic :
78- try :
79- obj = obj .sort_index (axis = self .axis )
80- except TypeError :
81- obj = obj .sort_index ()
82-
83- if isinstance (axis , DatetimeIndex ):
77+ obj = self ._ensure_sortedness (obj )
78+ if isinstance (ax , DatetimeIndex ):
8479 rs = self ._resample_timestamps (obj )
85- elif isinstance (axis , PeriodIndex ):
80+ elif isinstance (ax , PeriodIndex ):
8681 offset = to_offset (self .freq )
8782 if offset .n > 1 :
8883 if self .kind == 'period' : # pragma: no cover
@@ -95,55 +90,68 @@ def resample(self, obj):
9590 else :
9691 obj = obj .to_timestamp (how = self .convention )
9792 rs = self ._resample_timestamps (obj )
98- elif len (axis ) == 0 :
93+ elif len (ax ) == 0 :
9994 return obj
10095 else : # pragma: no cover
10196 raise TypeError ('Only valid with DatetimeIndex or PeriodIndex' )
10297
10398 rs_axis = rs ._get_axis (self .axis )
104- rs_axis .name = axis .name
99+ rs_axis .name = ax .name
105100 return rs
106101
107102 def get_grouper (self , obj ):
108- # Only return grouper
109- return self ._get_time_grouper (obj )[1 ]
103+ # return a tuple of (binner, grouper, obj)
104+ return self ._get_time_grouper (obj )
105+
106+ def _ensure_sortedness (self , obj ):
107+ # ensure that our object is sorted
108+ ax = obj ._get_axis (self .axis )
109+ if not ax .is_monotonic :
110+ try :
111+ obj = obj .sort_index (axis = self .axis )
112+ except TypeError :
113+ obj = obj .sort_index ()
114+ return obj
110115
111116 def _get_time_grouper (self , obj ):
112- axis = obj ._get_axis (self .axis )
117+ obj = self ._ensure_sortedness (obj )
118+ ax = obj ._get_axis (self .axis )
113119
114120 if self .kind is None or self .kind == 'timestamp' :
115- binner , bins , binlabels = self ._get_time_bins (axis )
121+ binner , bins , binlabels = self ._get_time_bins (ax )
116122 else :
117- binner , bins , binlabels = self ._get_time_period_bins (axis )
123+ binner , bins , binlabels = self ._get_time_period_bins (ax )
118124
119125 grouper = BinGrouper (bins , binlabels )
120- return binner , grouper
126+ return binner , grouper , obj
121127
122- def _get_time_bins (self , axis ):
123- if not isinstance (axis , DatetimeIndex ):
128+ def _get_time_bins (self , ax ):
129+ if not isinstance (ax , DatetimeIndex ):
124130 raise TypeError ('axis must be a DatetimeIndex, but got '
125- 'an instance of %r' % type (axis ).__name__ )
131+ 'an instance of %r' % type (ax ).__name__ )
126132
127- if len (axis ) == 0 :
128- binner = labels = DatetimeIndex (data = [], freq = self .freq )
133+ if len (ax ) == 0 :
134+ binner = labels = DatetimeIndex (data = [], freq = self .freq , name = ax . name )
129135 return binner , [], labels
130136
131- first , last = _get_range_edges (axis , self .freq , closed = self .closed ,
137+ first , last = _get_range_edges (ax , self .freq , closed = self .closed ,
132138 base = self .base )
133- tz = axis .tz
139+ tz = ax .tz
134140 binner = labels = DatetimeIndex (freq = self .freq ,
135141 start = first .replace (tzinfo = None ),
136- end = last .replace (tzinfo = None ), tz = tz )
142+ end = last .replace (tzinfo = None ),
143+ tz = tz ,
144+ name = ax .name )
137145
138146 # a little hack
139147 trimmed = False
140- if (len (binner ) > 2 and binner [- 2 ] == axis [- 1 ] and
148+ if (len (binner ) > 2 and binner [- 2 ] == ax [- 1 ] and
141149 self .closed == 'right' ):
142150
143151 binner = binner [:- 1 ]
144152 trimmed = True
145153
146- ax_values = axis .asi8
154+ ax_values = ax .asi8
147155 binner , bin_edges = self ._adjust_bin_edges (binner , ax_values )
148156
149157 # general version, knowing nothing about relative frequencies
@@ -180,22 +188,24 @@ def _adjust_bin_edges(self, binner, ax_values):
180188
181189 return binner , bin_edges
182190
183- def _get_time_period_bins (self , axis ):
184- if not isinstance (axis , DatetimeIndex ):
191+ def _get_time_period_bins (self , ax ):
192+ if not isinstance (ax , DatetimeIndex ):
185193 raise TypeError ('axis must be a DatetimeIndex, but got '
186- 'an instance of %r' % type (axis ).__name__ )
194+ 'an instance of %r' % type (ax ).__name__ )
187195
188- if not len (axis ):
189- binner = labels = PeriodIndex (data = [], freq = self .freq )
196+ if not len (ax ):
197+ binner = labels = PeriodIndex (data = [], freq = self .freq , name = ax . name )
190198 return binner , [], labels
191199
192- labels = binner = PeriodIndex (start = axis [0 ], end = axis [- 1 ],
193- freq = self .freq )
200+ labels = binner = PeriodIndex (start = ax [0 ],
201+ end = ax [- 1 ],
202+ freq = self .freq ,
203+ name = ax .name )
194204
195205 end_stamps = (labels + 1 ).asfreq (self .freq , 's' ).to_timestamp ()
196- if axis .tzinfo :
197- end_stamps = end_stamps .tz_localize (axis .tzinfo )
198- bins = axis .searchsorted (end_stamps , side = 'left' )
206+ if ax .tzinfo :
207+ end_stamps = end_stamps .tz_localize (ax .tzinfo )
208+ bins = ax .searchsorted (end_stamps , side = 'left' )
199209
200210 return binner , bins , labels
201211
@@ -206,7 +216,7 @@ def _agg_method(self):
206216 def _resample_timestamps (self , obj ):
207217 axlabels = obj ._get_axis (self .axis )
208218
209- binner , grouper = self ._get_time_grouper (obj )
219+ binner , grouper , _ = self ._get_time_grouper (obj )
210220
211221 # Determine if we're downsampling
212222 if axlabels .freq is not None or axlabels .inferred_freq is not None :
0 commit comments