Skip to content

Commit

Permalink
Backport PR #49676 on branch 1.5.x (REGR: Remove groupby's __getattri…
Browse files Browse the repository at this point in the history
…bute__ for nth) (#49705)

* Backport PR #49676: REGR: Remove groupby's __getattribute__ for nth

Co-authored-by: Richard Shadrach <45562402+rhshadrach@users.noreply.github.com>
  • Loading branch information
meeseeksmachine and rhshadrach committed Nov 16, 2022
1 parent 136271a commit 63a91d0
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 17 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.5.2.rst
Expand Up @@ -18,6 +18,7 @@ Fixed regressions
- Fixed regression in :meth:`DataFrame.plot` preventing :class:`~matplotlib.colors.Colormap` instance
from being passed using the ``colormap`` argument if Matplotlib 3.6+ is used (:issue:`49374`)
- Fixed regression in :func:`date_range` returning an invalid set of periods for ``CustomBusinessDay`` frequency and ``start`` date with timezone (:issue:`49441`)
- Fixed performance regression in groupby operations (:issue:`49676`)
-

.. ---------------------------------------------------------------------------
Expand Down
27 changes: 12 additions & 15 deletions pandas/core/groupby/groupby.py
Expand Up @@ -982,15 +982,6 @@ def __getattr__(self, attr: str):
f"'{type(self).__name__}' object has no attribute '{attr}'"
)

def __getattribute__(self, attr: str):
# Intercept nth to allow both call and index
if attr == "nth":
return GroupByNthSelector(self)
elif attr == "nth_actual":
return super().__getattribute__("nth")
else:
return super().__getattribute__(attr)

@final
def _make_wrapper(self, name: str) -> Callable:
assert name in self._apply_allowlist
Expand Down Expand Up @@ -3015,14 +3006,13 @@ def backfill(self, limit=None):
)
return self.bfill(limit=limit)

@final
# https://github.com/python/mypy/issues/1362
# Mypy does not support decorated properties
@final # type: ignore[misc]
@property
@Substitution(name="groupby")
@Substitution(see_also=_common_see_also)
def nth(
self,
n: PositionalIndexer | tuple,
dropna: Literal["any", "all", None] = None,
) -> NDFrameT:
def nth(self) -> GroupByNthSelector:
"""
Take the nth row from each group if n is an int, otherwise a subset of rows.
Expand Down Expand Up @@ -3125,6 +3115,13 @@ def nth(
1 1 2.0
4 2 5.0
"""
return GroupByNthSelector(self)

def _nth(
self,
n: PositionalIndexer | tuple,
dropna: Literal["any", "all", None] = None,
) -> NDFrameT:
if not dropna:
with self._group_selection_context():
mask = self._make_mask_from_positional_indexer(n)
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/groupby/indexing.py
Expand Up @@ -297,7 +297,7 @@ def __call__(
n: PositionalIndexer | tuple,
dropna: Literal["any", "all", None] = None,
) -> DataFrame | Series:
return self.groupby_object.nth_actual(n, dropna)
return self.groupby_object._nth(n, dropna)

def __getitem__(self, n: PositionalIndexer | tuple) -> DataFrame | Series:
return self.groupby_object.nth_actual(n)
return self.groupby_object._nth(n)

0 comments on commit 63a91d0

Please sign in to comment.