@@ -72,17 +72,12 @@ def __init__(self, freq='Min', closed=None, label=None, how='mean',
72
72
self .base = base
73
73
74
74
def resample (self , obj ):
75
- axis = obj ._get_axis (self .axis )
75
+ ax = obj ._get_axis (self .axis )
76
76
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 ):
84
79
rs = self ._resample_timestamps (obj )
85
- elif isinstance (axis , PeriodIndex ):
80
+ elif isinstance (ax , PeriodIndex ):
86
81
offset = to_offset (self .freq )
87
82
if offset .n > 1 :
88
83
if self .kind == 'period' : # pragma: no cover
@@ -95,55 +90,68 @@ def resample(self, obj):
95
90
else :
96
91
obj = obj .to_timestamp (how = self .convention )
97
92
rs = self ._resample_timestamps (obj )
98
- elif len (axis ) == 0 :
93
+ elif len (ax ) == 0 :
99
94
return obj
100
95
else : # pragma: no cover
101
96
raise TypeError ('Only valid with DatetimeIndex or PeriodIndex' )
102
97
103
98
rs_axis = rs ._get_axis (self .axis )
104
- rs_axis .name = axis .name
99
+ rs_axis .name = ax .name
105
100
return rs
106
101
107
102
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
110
115
111
116
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 )
113
119
114
120
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 )
116
122
else :
117
- binner , bins , binlabels = self ._get_time_period_bins (axis )
123
+ binner , bins , binlabels = self ._get_time_period_bins (ax )
118
124
119
125
grouper = BinGrouper (bins , binlabels )
120
- return binner , grouper
126
+ return binner , grouper , obj
121
127
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 ):
124
130
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__ )
126
132
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 )
129
135
return binner , [], labels
130
136
131
- first , last = _get_range_edges (axis , self .freq , closed = self .closed ,
137
+ first , last = _get_range_edges (ax , self .freq , closed = self .closed ,
132
138
base = self .base )
133
- tz = axis .tz
139
+ tz = ax .tz
134
140
binner = labels = DatetimeIndex (freq = self .freq ,
135
141
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 )
137
145
138
146
# a little hack
139
147
trimmed = False
140
- if (len (binner ) > 2 and binner [- 2 ] == axis [- 1 ] and
148
+ if (len (binner ) > 2 and binner [- 2 ] == ax [- 1 ] and
141
149
self .closed == 'right' ):
142
150
143
151
binner = binner [:- 1 ]
144
152
trimmed = True
145
153
146
- ax_values = axis .asi8
154
+ ax_values = ax .asi8
147
155
binner , bin_edges = self ._adjust_bin_edges (binner , ax_values )
148
156
149
157
# general version, knowing nothing about relative frequencies
@@ -180,22 +188,24 @@ def _adjust_bin_edges(self, binner, ax_values):
180
188
181
189
return binner , bin_edges
182
190
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 ):
185
193
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__ )
187
195
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 )
190
198
return binner , [], labels
191
199
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 )
194
204
195
205
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' )
199
209
200
210
return binner , bins , labels
201
211
@@ -206,7 +216,7 @@ def _agg_method(self):
206
216
def _resample_timestamps (self , obj ):
207
217
axlabels = obj ._get_axis (self .axis )
208
218
209
- binner , grouper = self ._get_time_grouper (obj )
219
+ binner , grouper , _ = self ._get_time_grouper (obj )
210
220
211
221
# Determine if we're downsampling
212
222
if axlabels .freq is not None or axlabels .inferred_freq is not None :
0 commit comments