Skip to content

Commit 5b6c5d1

Browse files
authored
REF: dont rely on Grouper.ax (#51184)
* REF: dont rely on Grouper.axis * mypy fixup * update docstring
1 parent 1efc2d7 commit 5b6c5d1

File tree

2 files changed

+32
-28
lines changed

2 files changed

+32
-28
lines changed

Diff for: pandas/core/groupby/grouper.py

+14-8
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
TYPE_CHECKING,
99
Hashable,
1010
Iterator,
11-
cast,
1211
final,
1312
)
1413
import warnings
@@ -300,9 +299,9 @@ def _get_grouper(
300299
-------
301300
a tuple of grouper, obj (possibly sorted)
302301
"""
303-
self._set_grouper(obj)
302+
obj, _ = self._set_grouper(obj)
304303
grouper, _, obj = get_grouper(
305-
cast(NDFrameT, self.obj),
304+
obj,
306305
[self.key],
307306
axis=self.axis,
308307
level=self.level,
@@ -318,7 +317,9 @@ def _get_grouper(
318317
return grouper, obj
319318

320319
@final
321-
def _set_grouper(self, obj: NDFrame, sort: bool = False) -> None:
320+
def _set_grouper(
321+
self, obj: NDFrame, sort: bool = False, *, gpr_index: Index | None = None
322+
):
322323
"""
323324
given an object and the specifications, setup the internal grouper
324325
for this particular specification
@@ -328,6 +329,12 @@ def _set_grouper(self, obj: NDFrame, sort: bool = False) -> None:
328329
obj : Series or DataFrame
329330
sort : bool, default False
330331
whether the resulting grouper should be sorted
332+
gpr_index : Index or None, default None
333+
334+
Returns
335+
-------
336+
NDFrame
337+
Index
331338
"""
332339
assert obj is not None
333340

@@ -337,16 +344,14 @@ def _set_grouper(self, obj: NDFrame, sort: bool = False) -> None:
337344
# Keep self._grouper value before overriding
338345
if self._grouper is None:
339346
# TODO: What are we assuming about subsequent calls?
340-
self._grouper = self._gpr_index
347+
self._grouper = gpr_index
341348
self._indexer = self.indexer
342349

343350
# the key must be a valid info item
344351
if self.key is not None:
345352
key = self.key
346353
# The 'on' is already defined
347-
if getattr(self._gpr_index, "name", None) == key and isinstance(
348-
obj, Series
349-
):
354+
if getattr(gpr_index, "name", None) == key and isinstance(obj, Series):
350355
# Sometimes self._grouper will have been resorted while
351356
# obj has not. In this case there is a mismatch when we
352357
# call self._grouper.take(obj.index) so we need to undo the sorting
@@ -392,6 +397,7 @@ def _set_grouper(self, obj: NDFrame, sort: bool = False) -> None:
392397
# "NDFrameT", variable has type "None")
393398
self.obj = obj # type: ignore[assignment]
394399
self._gpr_index = ax
400+
return obj, ax
395401

396402
@final
397403
@property

Diff for: pandas/core/resample.py

+18-20
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ class Resampler(BaseGroupBy, PandasObject):
133133
_timegrouper: TimeGrouper
134134
binner: DatetimeIndex | TimedeltaIndex | PeriodIndex # depends on subclass
135135
exclusions: frozenset[Hashable] = frozenset() # for SelectionMixin compat
136+
_internal_names_set = set({"obj", "ax"})
136137

137138
# to the groupby descriptor
138139
_attributes = [
@@ -153,6 +154,7 @@ def __init__(
153154
axis: Axis = 0,
154155
kind=None,
155156
*,
157+
gpr_index: Index,
156158
group_keys: bool | lib.NoDefault = lib.no_default,
157159
selection=None,
158160
) -> None:
@@ -166,7 +168,9 @@ def __init__(
166168
self.group_keys = group_keys
167169
self.as_index = True
168170

169-
self._timegrouper._set_grouper(self._convert_obj(obj), sort=True)
171+
self.obj, self.ax = self._timegrouper._set_grouper(
172+
self._convert_obj(obj), sort=True, gpr_index=gpr_index
173+
)
170174
self.binner, self.grouper = self._get_binner()
171175
self._selection = selection
172176
if self._timegrouper.key is not None:
@@ -195,19 +199,6 @@ def __getattr__(self, attr: str):
195199

196200
return object.__getattribute__(self, attr)
197201

198-
# error: Signature of "obj" incompatible with supertype "BaseGroupBy"
199-
@property
200-
def obj(self) -> NDFrame: # type: ignore[override]
201-
# error: Incompatible return value type (got "Optional[Any]",
202-
# expected "NDFrameT")
203-
return self._timegrouper.obj # type: ignore[return-value]
204-
205-
@property
206-
def ax(self):
207-
# we can infer that this is a PeriodIndex/DatetimeIndex/TimedeltaIndex,
208-
# but skipping annotating bc the overrides overwhelming
209-
return self._timegrouper.ax
210-
211202
@property
212203
def _from_selection(self) -> bool:
213204
"""
@@ -1189,6 +1180,9 @@ def __init__(
11891180
self._groupby = groupby
11901181
self._timegrouper = copy.copy(parent._timegrouper)
11911182

1183+
self.ax = parent.ax
1184+
self.obj = parent.obj
1185+
11921186
@no_type_check
11931187
def _apply(self, f, *args, **kwargs):
11941188
"""
@@ -1197,7 +1191,7 @@ def _apply(self, f, *args, **kwargs):
11971191
"""
11981192

11991193
def func(x):
1200-
x = self._resampler_cls(x, timegrouper=self._timegrouper)
1194+
x = self._resampler_cls(x, timegrouper=self._timegrouper, gpr_index=self.ax)
12011195

12021196
if isinstance(f, str):
12031197
return getattr(x, f)(**kwargs)
@@ -1226,8 +1220,7 @@ def _gotitem(self, key, ndim, subset=None):
12261220
"""
12271221
# create a new object to prevent aliasing
12281222
if subset is None:
1229-
# error: "GotItemMixin" has no attribute "obj"
1230-
subset = self.obj # type: ignore[attr-defined]
1223+
subset = self.obj
12311224

12321225
# Try to select from a DataFrame, falling back to a Series
12331226
try:
@@ -1688,16 +1681,16 @@ def _get_resampler(self, obj: NDFrame, kind=None) -> Resampler:
16881681
TypeError if incompatible axis
16891682
16901683
"""
1691-
self._set_grouper(obj)
1684+
_, ax = self._set_grouper(obj, gpr_index=None)
16921685

1693-
ax = self.ax
16941686
if isinstance(ax, DatetimeIndex):
16951687
return DatetimeIndexResampler(
16961688
obj,
16971689
timegrouper=self,
16981690
kind=kind,
16991691
axis=self.axis,
17001692
group_keys=self.group_keys,
1693+
gpr_index=ax,
17011694
)
17021695
elif isinstance(ax, PeriodIndex) or kind == "period":
17031696
return PeriodIndexResampler(
@@ -1706,10 +1699,15 @@ def _get_resampler(self, obj: NDFrame, kind=None) -> Resampler:
17061699
kind=kind,
17071700
axis=self.axis,
17081701
group_keys=self.group_keys,
1702+
gpr_index=ax,
17091703
)
17101704
elif isinstance(ax, TimedeltaIndex):
17111705
return TimedeltaIndexResampler(
1712-
obj, timegrouper=self, axis=self.axis, group_keys=self.group_keys
1706+
obj,
1707+
timegrouper=self,
1708+
axis=self.axis,
1709+
group_keys=self.group_keys,
1710+
gpr_index=ax,
17131711
)
17141712

17151713
raise TypeError(

0 commit comments

Comments
 (0)