nodes: 0, module; 1, function_definition; 2, function_name:_set_grouper; 3, parameters; 4, block; 5, identifier:self; 6, identifier:obj; 7, default_parameter; 8, expression_statement; 9, if_statement; 10, comment:# Keep self.grouper value before overriding; 11, if_statement; 12, comment:# the key must be a valid info item; 13, if_statement; 14, comment:# possibly sort; 15, if_statement; 16, expression_statement; 17, expression_statement; 18, return_statement; 19, identifier:sort; 20, False; 21, comment:"""
          given an object and the specifications, setup the internal grouper
          for this particular specification
  
          Parameters
          ----------
          obj : the subject object
          sort : bool, default False
              whether the resulting grouper should be sorted
          """; 22, boolean_operator; 23, block; 24, comparison_operator:self._grouper is None; 25, block; 26, comparison_operator:self.key is not None; 27, block; 28, else_clause; 29, boolean_operator; 30, comment:# use stable sort to support first, last, nth; 31, block; 32, assignment; 33, assignment; 34, attribute; 35, comparison_operator:self.key is not None; 36, comparison_operator:self.level is not None; 37, raise_statement; 38, attribute; 39, None; 40, expression_statement; 41, attribute; 42, None; 43, expression_statement; 44, comment:# The 'on' is already defined; 45, if_statement; 46, block; 47, parenthesized_expression; 48, not_operator; 49, expression_statement; 50, expression_statement; 51, expression_statement; 52, attribute; 53, identifier:obj; 54, attribute; 55, identifier:ax; 56, identifier:self; 57, identifier:grouper; 58, attribute; 59, None; 60, attribute; 61, None; 62, call; 63, identifier:self; 64, identifier:_grouper; 65, assignment; 66, identifier:self; 67, identifier:key; 68, assignment; 69, parenthesized_expression; 70, block; 71, else_clause; 72, expression_statement; 73, if_statement; 74, boolean_operator; 75, attribute; 76, assignment; 77, assignment; 78, assignment; 79, identifier:self; 80, identifier:obj; 81, identifier:self; 82, identifier:grouper; 83, identifier:self; 84, identifier:key; 85, identifier:self; 86, identifier:level; 87, identifier:ValueError; 88, argument_list; 89, attribute; 90, attribute; 91, identifier:key; 92, attribute; 93, boolean_operator; 94, expression_statement; 95, block; 96, assignment; 97, comparison_operator:self.level is not None; 98, block; 99, attribute; 100, identifier:sort; 101, identifier:ax; 102, identifier:is_monotonic; 103, identifier:indexer; 104, assignment; 105, identifier:ax; 106, call; 107, identifier:obj; 108, call; 109, string:"The Grouper cannot specify both a key and a level!"; 110, identifier:self; 111, identifier:_grouper; 112, identifier:self; 113, identifier:grouper; 114, identifier:self; 115, identifier:key; 116, comparison_operator:getattr(self.grouper, 'name', None) == key; 117, call; 118, assignment; 119, if_statement; 120, expression_statement; 121, identifier:ax; 122, call; 123, attribute; 124, None; 125, expression_statement; 126, comment:# if a level is given it must be a mi level or; 127, comment:# equivalent to the axis name; 128, if_statement; 129, identifier:self; 130, identifier:sort; 131, attribute; 132, call; 133, attribute; 134, argument_list; 135, attribute; 136, argument_list; 137, call; 138, identifier:key; 139, identifier:isinstance; 140, argument_list; 141, identifier:ax; 142, call; 143, comparison_operator:key not in obj._info_axis; 144, block; 145, assignment; 146, attribute; 147, argument_list; 148, identifier:self; 149, identifier:level; 150, assignment; 151, call; 152, block; 153, else_clause; 154, identifier:self; 155, identifier:indexer; 156, attribute; 157, argument_list; 158, identifier:ax; 159, identifier:take; 160, identifier:indexer; 161, identifier:obj; 162, identifier:_take; 163, identifier:indexer; 164, keyword_argument; 165, keyword_argument; 166, identifier:getattr; 167, argument_list; 168, identifier:obj; 169, identifier:ABCSeries; 170, attribute; 171, argument_list; 172, identifier:key; 173, attribute; 174, raise_statement; 175, identifier:ax; 176, call; 177, identifier:obj; 178, identifier:_get_axis; 179, attribute; 180, identifier:level; 181, attribute; 182, identifier:isinstance; 183, argument_list; 184, expression_statement; 185, expression_statement; 186, block; 187, identifier:ax; 188, identifier:argsort; 189, keyword_argument; 190, identifier:axis; 191, attribute; 192, identifier:is_copy; 193, False; 194, attribute; 195, string; 196, None; 197, attribute; 198, identifier:take; 199, attribute; 200, identifier:obj; 201, identifier:_info_axis; 202, call; 203, identifier:Index; 204, argument_list; 205, identifier:self; 206, identifier:axis; 207, identifier:self; 208, identifier:level; 209, identifier:ax; 210, identifier:MultiIndex; 211, assignment; 212, assignment; 213, if_statement; 214, identifier:kind; 215, string; 216, identifier:self; 217, identifier:axis; 218, identifier:self; 219, identifier:grouper; 220, string_content:name; 221, identifier:self; 222, identifier:_grouper; 223, identifier:obj; 224, identifier:index; 225, identifier:KeyError; 226, argument_list; 227, subscript; 228, keyword_argument; 229, identifier:level; 230, call; 231, identifier:ax; 232, call; 233, comparison_operator:level not in (0, ax.name); 234, block; 235, string_content:mergesort; 236, call; 237, identifier:obj; 238, identifier:key; 239, identifier:name; 240, identifier:key; 241, attribute; 242, argument_list; 243, identifier:Index; 244, argument_list; 245, identifier:level; 246, tuple; 247, raise_statement; 248, attribute; 249, argument_list; 250, identifier:ax; 251, identifier:_get_level_number; 252, identifier:level; 253, call; 254, keyword_argument; 255, integer:0; 256, attribute; 257, call; 258, string:"The grouper name {0} is not found"; 259, identifier:format; 260, identifier:key; 261, attribute; 262, argument_list; 263, identifier:name; 264, subscript; 265, identifier:ax; 266, identifier:name; 267, identifier:ValueError; 268, argument_list; 269, identifier:ax; 270, identifier:_get_level_values; 271, identifier:level; 272, attribute; 273, identifier:level; 274, call; 275, identifier:ax; 276, identifier:names; 277, attribute; 278, argument_list; 279, string:"The level {0} is not valid"; 280, identifier:format; 281, identifier:level
code: def _set_grouper(self, obj, sort=False):
          """
          given an object and the specifications, setup the internal grouper
          for this particular specification
  
          Parameters
          ----------
          obj : the subject object
          sort : bool, default False
              whether the resulting grouper should be sorted
          """
  
          if self.key is not None and self.level is not None:
              raise ValueError(
                  "The Grouper cannot specify both a key and a level!")
  
          # Keep self.grouper value before overriding
          if self._grouper is None:
              self._grouper = self.grouper
  
          # the key must be a valid info item
          if self.key is not None:
              key = self.key
              # The 'on' is already defined
              if (getattr(self.grouper, 'name', None) == key and
                      isinstance(obj, ABCSeries)):
                  ax = self._grouper.take(obj.index)
              else:
                  if key not in obj._info_axis:
                      raise KeyError(
                          "The grouper name {0} is not found".format(key))
                  ax = Index(obj[key], name=key)
  
          else:
              ax = obj._get_axis(self.axis)
              if self.level is not None:
                  level = self.level
  
                  # if a level is given it must be a mi level or
                  # equivalent to the axis name
                  if isinstance(ax, MultiIndex):
                      level = ax._get_level_number(level)
                      ax = Index(ax._get_level_values(level),
                                 name=ax.names[level])
  
                  else:
                      if level not in (0, ax.name):
                          raise ValueError(
                              "The level {0} is not valid".format(level))
  
          # possibly sort
          if (self.sort or sort) and not ax.is_monotonic:
              # use stable sort to support first, last, nth
              indexer = self.indexer = ax.argsort(kind='mergesort')
              ax = ax.take(indexer)
              obj = obj._take(indexer, axis=self.axis, is_copy=False)
  
          self.obj = obj
          self.grouper = ax
          return self.grouper