nodes: 0, module; 1, function_definition; 2, function_name:recode_for_groupby; 3, parameters; 4, block; 5, identifier:c; 6, identifier:sort; 7, identifier:observed; 8, expression_statement; 9, comment:# we only care about observed values; 10, if_statement; 11, comment:# Already sorted according to c.categories; all is fine; 12, if_statement; 13, comment:# sort=False should order groups in as-encountered order (GH-8868); 14, expression_statement; 15, comment:# But for groupby to work, all categories should be present,; 16, comment:# including those missing from the data (GH-13179), which .unique(); 17, comment:# above dropped; 18, expression_statement; 19, return_statement; 20, comment:"""
      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
      """; 21, identifier:observed; 22, block; 23, identifier:sort; 24, block; 25, assignment; 26, assignment; 27, expression_list; 28, expression_statement; 29, expression_statement; 30, if_statement; 31, comment:# we recode according to the uniques; 32, expression_statement; 33, expression_statement; 34, comment:# return a new categorical that maps our new codes; 35, comment:# and categories; 36, expression_statement; 37, return_statement; 38, return_statement; 39, identifier:cat; 40, call; 41, identifier:cat; 42, call; 43, call; 44, None; 45, assignment; 46, assignment; 47, attribute; 48, block; 49, assignment; 50, assignment; 51, assignment; 52, expression_list; 53, expression_list; 54, attribute; 55, argument_list; 56, attribute; 57, argument_list; 58, attribute; 59, argument_list; 60, identifier:unique_codes; 61, call; 62, identifier:take_codes; 63, subscript; 64, identifier:c; 65, identifier:ordered; 66, expression_statement; 67, identifier:categories; 68, call; 69, identifier:codes; 70, call; 71, identifier:dtype; 72, call; 73, call; 74, identifier:c; 75, identifier:c; 76, None; 77, identifier:c; 78, identifier:unique; 79, identifier:cat; 80, identifier:add_categories; 81, subscript; 82, identifier:c; 83, identifier:reorder_categories; 84, attribute; 85, identifier:unique1d; 86, argument_list; 87, identifier:unique_codes; 88, comparison_operator:unique_codes != -1; 89, assignment; 90, attribute; 91, argument_list; 92, identifier:_recode_for_categories; 93, argument_list; 94, identifier:CategoricalDtype; 95, argument_list; 96, identifier:Categorical; 97, argument_list; 98, attribute; 99, unary_operator; 100, identifier:cat; 101, identifier:categories; 102, attribute; 103, identifier:unique_codes; 104, unary_operator; 105, identifier:take_codes; 106, call; 107, attribute; 108, identifier:take; 109, identifier:take_codes; 110, attribute; 111, attribute; 112, identifier:categories; 113, identifier:categories; 114, keyword_argument; 115, identifier:codes; 116, keyword_argument; 117, keyword_argument; 118, identifier:c; 119, identifier:categories; 120, call; 121, identifier:c; 122, identifier:codes; 123, integer:1; 124, attribute; 125, argument_list; 126, identifier:c; 127, identifier:categories; 128, identifier:c; 129, identifier:codes; 130, identifier:c; 131, identifier:categories; 132, identifier:ordered; 133, attribute; 134, identifier:dtype; 135, identifier:dtype; 136, identifier:fastpath; 137, True; 138, attribute; 139, argument_list; 140, identifier:np; 141, identifier:sort; 142, identifier:take_codes; 143, identifier:c; 144, identifier:ordered; 145, attribute; 146, identifier:isin; 147, attribute; 148, identifier:c; 149, identifier:categories; 150, identifier:cat; 151, identifier:categories
code: def recode_for_groupby(c, sort, observed):
      """
      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
      """
  
      # we only care about observed values
      if observed:
          unique_codes = unique1d(c.codes)
  
          take_codes = unique_codes[unique_codes != -1]
          if c.ordered:
              take_codes = np.sort(take_codes)
  
          # we recode according to the uniques
          categories = c.categories.take(take_codes)
          codes = _recode_for_categories(c.codes,
                                         c.categories,
                                         categories)
  
          # return a new categorical that maps our new codes
          # and categories
          dtype = CategoricalDtype(categories, ordered=c.ordered)
          return Categorical(codes, dtype=dtype, fastpath=True), c
  
      # Already sorted according to c.categories; all is fine
      if sort:
          return c, None
  
      # sort=False should order groups in as-encountered order (GH-8868)
      cat = c.unique()
  
      # But for groupby to work, all categories should be present,
      # including those missing from the data (GH-13179), which .unique()
      # above dropped
      cat = cat.add_categories(
          c.categories[~c.categories.isin(cat.categories)])
  
      return c.reorder_categories(cat.categories), None