def recode_for_groupby(c, sort, observed):
<EOL>if observed:<EOL><INDENT>unique_codes = unique1d(c.codes)<EOL>take_codes = unique_codes[unique_codes != -<NUM_LIT:1>]<EOL>if c.ordered:<EOL><INDENT>take_codes = np.sort(take_codes)<EOL><DEDENT>categories = c.categories.take(take_codes)<EOL>codes = _recode_for_categories(c.codes,<EOL>c.categories,<EOL>categories)<EOL>dtype = CategoricalDtype(categories, ordered=c.ordered)<EOL>return Categorical(codes, dtype=dtype, fastpath=True), c<EOL><DEDENT>if sort:<EOL><INDENT>return c, None<EOL><DEDENT>cat = c.unique()<EOL>cat = cat.add_categories(<EOL>c.categories[~c.categories.isin(cat.categories)])<EOL>return c.reorder_categories(cat.categories), None<EOL>
Code the categories to ensure we can groupby for categoricals.

If observed=True, we return a new Categorical with the observed
categories only.

If sort=False, return a copy of self, coded with categories as
returned by .unique(), followed by any categories not appearing in
the data. If sort=True, return self.

This method is needed solely to ensure the categorical index of the
GroupBy result has categories in the order of appearance in the data
(GH-8868).

Parameters
----------
c : Categorical
sort : boolean
    The value of the sort parameter groupby was called with.
observed : boolean
    Account only for the observed values

Returns
-------
New Categorical
    If sort=False, the new categories are set to the order of
    appearance in codes (unless ordered=True, in which case the
    original order is preserved), followed by any unrepresented
    categories in the original order.
Categorical or None
    If we are observed, return the original categorical, otherwise None