import numpy as np
from pandas._typing import FrameOrSeries as FrameOrSeries
from pandas.core.arrays import Categorical as Categorical, ExtensionArray as ExtensionArray
from pandas.core.dtypes.common import ensure_categorical as ensure_categorical, is_categorical_dtype as is_categorical_dtype, is_datetime64_dtype as is_datetime64_dtype, is_list_like as is_list_like, is_scalar as is_scalar, is_timedelta64_dtype as is_timedelta64_dtype
from pandas.core.dtypes.generic import ABCSeries as ABCSeries
from pandas.core.frame import DataFrame as DataFrame
from pandas.core.groupby import ops as ops
from pandas.core.groupby.categorical import recode_for_groupby as recode_for_groupby, recode_from_groupby as recode_from_groupby
from pandas.core.indexes.api import CategoricalIndex as CategoricalIndex, Index as Index, MultiIndex as MultiIndex
from pandas.core.series import Series as Series
from pandas.io.formats.printing import pprint_thing as pprint_thing
from pandas.util._decorators import cache_readonly as cache_readonly
from typing import Any, Dict, Hashable, List, Optional, Tuple

class Grouper:
    def __new__(cls, *args: Any, **kwargs: Any) -> Any: ...
    key: Any = ...
    level: Any = ...
    freq: Any = ...
    axis: Any = ...
    sort: Any = ...
    grouper: Any = ...
    obj: Any = ...
    indexer: Any = ...
    binner: Any = ...
    def __init__(self, key: Optional[Any] = ..., level: Optional[Any] = ..., freq: Optional[Any] = ..., axis: int = ..., sort: bool = ...) -> None: ...
    @property
    def ax(self) -> Any: ...
    @property
    def groups(self) -> Any: ...

class Grouping:
    name: Any = ...
    level: Any = ...
    grouper: Any = ...
    all_grouper: Any = ...
    index: Any = ...
    sort: Any = ...
    obj: Any = ...
    observed: Any = ...
    in_axis: Any = ...
    def __init__(self, index: Index, grouper: Any = ..., obj: Optional[FrameOrSeries]=..., name: Any = ..., level: Any = ..., sort: bool=..., observed: bool=..., in_axis: bool=...) -> None: ...
    def __iter__(self) -> Any: ...
    @property
    def ngroups(self) -> int: ...
    def indices(self) -> Any: ...
    @property
    def codes(self) -> np.ndarray: ...
    def result_index(self) -> Index: ...
    @property
    def group_index(self) -> Index: ...
    def groups(self) -> Dict[Hashable, np.ndarray]: ...

def get_grouper(obj: FrameOrSeries, key: Any = ..., axis: int=..., level: Any = ..., sort: bool=..., observed: bool=..., mutated: bool=..., validate: bool=...) -> Tuple[ops.BaseGrouper, List[Hashable], FrameOrSeries]: ...
