Skip to content

CLN: Remove MultiIndex._get_grouper_for_level #49690

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
26 changes: 7 additions & 19 deletions pandas/core/groupby/grouper.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,19 +472,19 @@ def __init__(

ilevel = self._ilevel
if ilevel is not None:
mapper = self.grouping_vector
# In extant tests, the new self.grouping_vector matches
# `index.get_level_values(ilevel)` whenever
# mapper is None and isinstance(index, MultiIndex)
if isinstance(index, MultiIndex):
index_level = index.get_level_values(ilevel)
else:
index_level = index
(
self.grouping_vector, # Index
self._codes,
self._group_index,
) = index_level._get_grouper_for_level(mapper, dropna=dropna)

if self.grouping_vector is None:
self.grouping_vector = index_level
else:
mapper = self.grouping_vector
self.grouping_vector = index_level.map(mapper)

# a passed Grouper like, directly get the grouper in the same way
# as single grouper groupby, use the group_info to get codes
Expand Down Expand Up @@ -600,10 +600,6 @@ def indices(self) -> dict[Hashable, npt.NDArray[np.intp]]:

@property
def codes(self) -> npt.NDArray[np.signedinteger]:
if self._codes is not None:
# _codes is set in __init__ for MultiIndex cases
return self._codes

return self._codes_and_uniques[0]

@cache_readonly
Expand All @@ -612,11 +608,7 @@ def group_arraylike(self) -> ArrayLike:
Analogous to result_index, but holding an ArrayLike to ensure
we can retain ExtensionDtypes.
"""
if self._group_index is not None:
# _group_index is set in __init__ for MultiIndex cases
return self._group_index._values

elif self._all_grouper is not None:
if self._all_grouper is not None:
# retain dtype for categories, including unobserved ones
return self.result_index._values

Expand All @@ -636,10 +628,6 @@ def result_index(self) -> Index:

@cache_readonly
def group_index(self) -> Index:
if self._group_index is not None:
# _group_index is set in __init__ for MultiIndex cases
return self._group_index

uniques = self._codes_and_uniques[1]
return Index._with_infer(uniques, name=self.name)

Expand Down
36 changes: 0 additions & 36 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2062,42 +2062,6 @@ def _drop_level_numbers(self, levnums: list[int]):
verify_integrity=False,
)

def _get_grouper_for_level(
self,
mapper,
*,
level=None,
dropna: bool = True,
) -> tuple[Index, npt.NDArray[np.signedinteger] | None, Index | None]:
"""
Get index grouper corresponding to an index level

Parameters
----------
mapper: Group mapping function or None
Function mapping index values to groups
level : int or None
Index level, positional
dropna : bool
dropna from groupby

Returns
-------
grouper : Index
Index of values to group on.
labels : ndarray of int or None
Array of locations in level_index.
uniques : Index or None
Index of unique values for level.
"""
assert level is None or level == 0
if mapper is None:
grouper = self
else:
grouper = self.map(mapper)

return grouper, None, None

# --------------------------------------------------------------------
# Introspection Methods

Expand Down
26 changes: 0 additions & 26 deletions pandas/core/indexes/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -1458,32 +1458,6 @@ def _set_names(self, names, *, level=None, validate: bool = True):

# --------------------------------------------------------------------

@doc(Index._get_grouper_for_level)
def _get_grouper_for_level(
self,
mapper,
*,
level=None,
dropna: bool = True,
) -> tuple[Index, npt.NDArray[np.signedinteger] | None, Index | None]:
if mapper is not None:
indexer = self.codes[level]
# Handle group mapping function and return
level_values = self.levels[level].take(indexer)
grouper = level_values.map(mapper)
return grouper, None, None

values = self.get_level_values(level)
codes, uniques = algos.factorize(values, sort=True, use_na_sentinel=dropna)
assert isinstance(uniques, Index)

if self.levels[level]._can_hold_na:
grouper = uniques.take(codes, fill_value=True)
else:
grouper = uniques.take(codes)

return grouper, codes, uniques

@cache_readonly
def inferred_type(self) -> str:
return "mixed"
Expand Down