6
6
from typing import (
7
7
TYPE_CHECKING ,
8
8
Callable ,
9
+ Hashable ,
9
10
no_type_check ,
10
11
)
11
12
@@ -101,8 +102,8 @@ class Resampler(BaseGroupBy, PandasObject):
101
102
102
103
Parameters
103
104
----------
104
- obj : pandas object
105
- groupby : a TimeGrouper object
105
+ obj : Series or DataFrame
106
+ groupby : TimeGrouper
106
107
axis : int, default 0
107
108
kind : str or None
108
109
'period', 'timestamp' to override default index treatment
@@ -116,10 +117,8 @@ class Resampler(BaseGroupBy, PandasObject):
116
117
After resampling, see aggregate, apply, and transform functions.
117
118
"""
118
119
119
- # error: Incompatible types in assignment (expression has type
120
- # "Optional[BinGrouper]", base class "BaseGroupBy" defined the type as
121
- # "BaseGrouper")
122
- grouper : BinGrouper | None # type: ignore[assignment]
120
+ grouper : BinGrouper
121
+ exclusions : frozenset [Hashable ] = frozenset () # for SelectionMixin compat
123
122
124
123
# to the groupby descriptor
125
124
_attributes = [
@@ -134,7 +133,14 @@ class Resampler(BaseGroupBy, PandasObject):
134
133
"offset" ,
135
134
]
136
135
137
- def __init__ (self , obj , groupby = None , axis = 0 , kind = None , ** kwargs ):
136
+ def __init__ (
137
+ self ,
138
+ obj : FrameOrSeries ,
139
+ groupby : TimeGrouper ,
140
+ axis : int = 0 ,
141
+ kind = None ,
142
+ ** kwargs ,
143
+ ):
138
144
self .groupby = groupby
139
145
self .keys = None
140
146
self .sort = True
@@ -143,12 +149,9 @@ def __init__(self, obj, groupby=None, axis=0, kind=None, **kwargs):
143
149
self .squeeze = False
144
150
self .group_keys = True
145
151
self .as_index = True
146
- self .exclusions = set ()
147
- self .binner = None
148
- self .grouper = None
149
152
150
- if self .groupby is not None :
151
- self .groupby . _set_grouper ( self ._convert_obj ( obj ), sort = True )
153
+ self .groupby . _set_grouper ( self . _convert_obj ( obj ), sort = True )
154
+ self .binner , self .grouper = self . _get_binner ( )
152
155
153
156
@final
154
157
def _shallow_copy (self , obj , ** kwargs ):
@@ -183,25 +186,12 @@ def __getattr__(self, attr: str):
183
186
184
187
return object .__getattribute__ (self , attr )
185
188
186
- def __iter__ (self ):
187
- """
188
- Resampler iterator.
189
-
190
- Returns
191
- -------
192
- Generator yielding sequence of (name, subsetted object)
193
- for each group.
194
-
195
- See Also
196
- --------
197
- GroupBy.__iter__ : Generator yielding sequence for each group.
198
- """
199
- self ._set_binner ()
200
- return super ().__iter__ ()
201
-
189
+ # error: Signature of "obj" incompatible with supertype "BaseGroupBy"
202
190
@property
203
- def obj (self ):
204
- return self .groupby .obj
191
+ def obj (self ) -> FrameOrSeries : # type: ignore[override]
192
+ # error: Incompatible return value type (got "Optional[Any]",
193
+ # expected "FrameOrSeries")
194
+ return self .groupby .obj # type: ignore[return-value]
205
195
206
196
@property
207
197
def ax (self ):
@@ -218,32 +208,24 @@ def _from_selection(self) -> bool:
218
208
self .groupby .key is not None or self .groupby .level is not None
219
209
)
220
210
221
- def _convert_obj (self , obj ) :
211
+ def _convert_obj (self , obj : FrameOrSeries ) -> FrameOrSeries :
222
212
"""
223
213
Provide any conversions for the object in order to correctly handle.
224
214
225
215
Parameters
226
216
----------
227
- obj : the object to be resampled
217
+ obj : Series or DataFrame
228
218
229
219
Returns
230
220
-------
231
- obj : converted object
221
+ Series or DataFrame
232
222
"""
233
223
return obj ._consolidate ()
234
224
235
225
def _get_binner_for_time (self ):
236
226
raise AbstractMethodError (self )
237
227
238
- def _set_binner (self ):
239
- """
240
- Setup our binners.
241
-
242
- Cache these as we are an immutable object
243
- """
244
- if self .binner is None :
245
- self .binner , self .grouper = self ._get_binner ()
246
-
228
+ @final
247
229
def _get_binner (self ):
248
230
"""
249
231
Create the BinGrouper, assume that self.set_grouper(obj)
@@ -254,12 +236,6 @@ def _get_binner(self):
254
236
bin_grouper = BinGrouper (bins , binlabels , indexer = self .groupby .indexer )
255
237
return binner , bin_grouper
256
238
257
- def _assure_grouper (self ):
258
- """
259
- Make sure that we are creating our binner & grouper.
260
- """
261
- self ._set_binner ()
262
-
263
239
@Substitution (
264
240
klass = "Resampler" ,
265
241
examples = """
@@ -349,7 +325,6 @@ def pipe(
349
325
)
350
326
def aggregate (self , func , * args , ** kwargs ):
351
327
352
- self ._set_binner ()
353
328
result = ResamplerWindowApply (self , func , args = args , kwargs = kwargs ).agg ()
354
329
if result is None :
355
330
how = func
@@ -400,7 +375,6 @@ def _gotitem(self, key, ndim: int, subset=None):
400
375
subset : object, default None
401
376
subset to act on
402
377
"""
403
- self ._set_binner ()
404
378
grouper = self .grouper
405
379
if subset is None :
406
380
subset = self .obj
@@ -417,7 +391,6 @@ def _groupby_and_aggregate(self, how, grouper=None, *args, **kwargs):
417
391
Re-evaluate the obj with a groupby aggregation.
418
392
"""
419
393
if grouper is None :
420
- self ._set_binner ()
421
394
grouper = self .grouper
422
395
423
396
obj = self ._selected_obj
@@ -1050,8 +1023,8 @@ def __init__(self, obj, parent=None, groupby=None, **kwargs):
1050
1023
for attr in self ._attributes :
1051
1024
setattr (self , attr , kwargs .get (attr , getattr (parent , attr )))
1052
1025
1053
- # error: Too many arguments for "__init__" of "object"
1054
- super (). __init__ ( None ) # type: ignore[call-arg]
1026
+ self . binner = parent . binner
1027
+
1055
1028
self ._groupby = groupby
1056
1029
self ._groupby .mutated = True
1057
1030
self ._groupby .grouper .mutated = True
@@ -1137,7 +1110,6 @@ def _downsample(self, how, **kwargs):
1137
1110
how : string / cython mapped function
1138
1111
**kwargs : kw args passed to how function
1139
1112
"""
1140
- self ._set_binner ()
1141
1113
how = com .get_cython_func (how ) or how
1142
1114
ax = self .ax
1143
1115
obj = self ._selected_obj
@@ -1154,7 +1126,7 @@ def _downsample(self, how, **kwargs):
1154
1126
# error: Item "None" of "Optional[Any]" has no attribute "binlabels"
1155
1127
if (
1156
1128
(ax .freq is not None or ax .inferred_freq is not None )
1157
- and len (self .grouper .binlabels ) > len (ax ) # type: ignore[union-attr]
1129
+ and len (self .grouper .binlabels ) > len (ax )
1158
1130
and how is None
1159
1131
):
1160
1132
@@ -1196,7 +1168,6 @@ def _upsample(self, method, limit=None, fill_value=None):
1196
1168
.fillna: Fill NA/NaN values using the specified method.
1197
1169
1198
1170
"""
1199
- self ._set_binner ()
1200
1171
if self .axis :
1201
1172
raise AssertionError ("axis must be 0" )
1202
1173
if self ._from_selection :
@@ -1257,7 +1228,7 @@ def _get_binner_for_time(self):
1257
1228
return super ()._get_binner_for_time ()
1258
1229
return self .groupby ._get_period_bins (self .ax )
1259
1230
1260
- def _convert_obj (self , obj ) :
1231
+ def _convert_obj (self , obj : FrameOrSeries ) -> FrameOrSeries :
1261
1232
obj = super ()._convert_obj (obj )
1262
1233
1263
1234
if self ._from_selection :
@@ -1336,7 +1307,6 @@ def _upsample(self, method, limit=None, fill_value=None):
1336
1307
if self .kind == "timestamp" :
1337
1308
return super ()._upsample (method , limit = limit , fill_value = fill_value )
1338
1309
1339
- self ._set_binner ()
1340
1310
ax = self .ax
1341
1311
obj = self .obj
1342
1312
new_index = self .binner
@@ -1349,9 +1319,7 @@ def _upsample(self, method, limit=None, fill_value=None):
1349
1319
new_obj = _take_new_index (
1350
1320
obj ,
1351
1321
indexer ,
1352
- # error: Argument 3 to "_take_new_index" has incompatible type
1353
- # "Optional[Any]"; expected "Index"
1354
- new_index , # type: ignore[arg-type]
1322
+ new_index ,
1355
1323
axis = self .axis ,
1356
1324
)
1357
1325
return self ._wrap_result (new_obj )
@@ -1511,20 +1479,20 @@ def __init__(
1511
1479
else :
1512
1480
try :
1513
1481
self .origin = Timestamp (origin )
1514
- except Exception as e :
1482
+ except ( ValueError , TypeError ) as err :
1515
1483
raise ValueError (
1516
1484
"'origin' should be equal to 'epoch', 'start', 'start_day', "
1517
1485
"'end', 'end_day' or "
1518
1486
f"should be a Timestamp convertible type. Got '{ origin } ' instead."
1519
- ) from e
1487
+ ) from err
1520
1488
1521
1489
try :
1522
1490
self .offset = Timedelta (offset ) if offset is not None else None
1523
- except Exception as e :
1491
+ except ( ValueError , TypeError ) as err :
1524
1492
raise ValueError (
1525
1493
"'offset' should be a Timedelta convertible type. "
1526
1494
f"Got '{ offset } ' instead."
1527
- ) from e
1495
+ ) from err
1528
1496
1529
1497
# always sort time groupers
1530
1498
kwargs ["sort" ] = True
@@ -1585,10 +1553,9 @@ def _get_resampler(self, obj, kind=None):
1585
1553
def _get_grouper (self , obj , validate : bool = True ):
1586
1554
# create the resampler and return our binner
1587
1555
r = self ._get_resampler (obj )
1588
- r ._set_binner ()
1589
1556
return r .binner , r .grouper , r .obj
1590
1557
1591
- def _get_time_bins (self , ax ):
1558
+ def _get_time_bins (self , ax : DatetimeIndex ):
1592
1559
if not isinstance (ax , DatetimeIndex ):
1593
1560
raise TypeError (
1594
1561
"axis must be a DatetimeIndex, but got "
@@ -1964,13 +1931,13 @@ def _insert_nat_bin(
1964
1931
1965
1932
1966
1933
def _adjust_dates_anchored (
1967
- first ,
1968
- last ,
1969
- freq ,
1934
+ first : Timestamp ,
1935
+ last : Timestamp ,
1936
+ freq : Tick ,
1970
1937
closed : Literal ["right" , "left" ] = "right" ,
1971
1938
origin = "start_day" ,
1972
1939
offset : Timedelta | None = None ,
1973
- ):
1940
+ ) -> tuple [ Timestamp , Timestamp ] :
1974
1941
# First and last offsets should be calculated from the start day to fix an
1975
1942
# error cause by resampling across multiple days when a one day period is
1976
1943
# not a multiple of the frequency. See GH 8683
0 commit comments