33split-apply-combine paradigm.
44"""
55
6- from typing import Optional , Tuple
6+ from typing import Hashable , List , Optional , Tuple
77import warnings
88
99import numpy as np
2626from pandas .core .arrays import Categorical , ExtensionArray
2727import pandas .core .common as com
2828from pandas .core .frame import DataFrame
29- from pandas .core .generic import NDFrame
3029from pandas .core .groupby .categorical import recode_for_groupby , recode_from_groupby
3130from pandas .core .groupby .ops import BaseGrouper
3231from pandas .core .index import CategoricalIndex , Index , MultiIndex
@@ -134,7 +133,7 @@ def _get_grouper(self, obj, validate=True):
134133 """
135134
136135 self ._set_grouper (obj )
137- self .grouper , exclusions , self .obj = _get_grouper (
136+ self .grouper , exclusions , self .obj = get_grouper (
138137 self .obj ,
139138 [self .key ],
140139 axis = self .axis ,
@@ -429,18 +428,18 @@ def groups(self) -> dict:
429428 return self .index .groupby (Categorical .from_codes (self .codes , self .group_index ))
430429
431430
432- def _get_grouper (
433- obj : NDFrame ,
431+ def get_grouper (
432+ obj : FrameOrSeries ,
434433 key = None ,
435434 axis : int = 0 ,
436435 level = None ,
437436 sort = True ,
438437 observed = False ,
439438 mutated = False ,
440439 validate = True ,
441- ):
440+ ) -> Tuple [ BaseGrouper , List [ Hashable ], FrameOrSeries ] :
442441 """
443- create and return a BaseGrouper, which is an internal
442+ Create and return a BaseGrouper, which is an internal
444443 mapping of how to create the grouper indexers.
445444 This may be composed of multiple Grouping objects, indicating
446445 multiple groupers
@@ -456,9 +455,9 @@ def _get_grouper(
456455 a BaseGrouper.
457456
458457 If observed & we have a categorical grouper, only show the observed
459- values
458+ values.
460459
461- If validate, then check for key/level overlaps
460+ If validate, then check for key/level overlaps.
462461
463462 """
464463 group_axis = obj ._get_axis (axis )
@@ -517,7 +516,7 @@ def _get_grouper(
517516 if key .key is None :
518517 return grouper , [], obj
519518 else :
520- return grouper , { key .key } , obj
519+ return grouper , [ key .key ] , obj
521520
522521 # already have a BaseGrouper, just return it
523522 elif isinstance (key , BaseGrouper ):
@@ -530,10 +529,8 @@ def _get_grouper(
530529 # unhashable elements of `key`. Any unhashable elements implies that
531530 # they wanted a list of keys.
532531 # https://github.com/pandas-dev/pandas/issues/18314
533- is_tuple = isinstance (key , tuple )
534- all_hashable = is_tuple and is_hashable (key )
535-
536- if is_tuple :
532+ if isinstance (key , tuple ):
533+ all_hashable = is_hashable (key )
537534 if (
538535 all_hashable and key not in obj and set (key ).issubset (obj )
539536 ) or not all_hashable :
@@ -573,7 +570,8 @@ def _get_grouper(
573570 all_in_columns_index = all (
574571 g in obj .columns or g in obj .index .names for g in keys
575572 )
576- elif isinstance (obj , Series ):
573+ else :
574+ assert isinstance (obj , Series )
577575 all_in_columns_index = all (g in obj .index .names for g in keys )
578576
579577 if not all_in_columns_index :
@@ -586,8 +584,8 @@ def _get_grouper(
586584 else :
587585 levels = [level ] * len (keys )
588586
589- groupings = []
590- exclusions = []
587+ groupings = [] # type: List[Grouping]
588+ exclusions = [] # type: List[Hashable]
591589
592590 # if the actual grouper should be obj[key]
593591 def is_in_axis (key ) -> bool :
0 commit comments