@classmethod<EOL><INDENT>def _add_numeric_operations(cls):<DEDENT>
def groupby_function(name, alias, npfunc,<EOL>numeric_only=True, _convert=False,<EOL>min_count=-<NUM_LIT:1>):<EOL><INDENT>_local_template = "<STR_LIT>"<EOL>@Substitution(name='<STR_LIT>', f=name)<EOL>@Appender(_common_see_also)<EOL>@Appender(_local_template)<EOL>def f(self, **kwargs):<EOL><INDENT>if '<STR_LIT>' not in kwargs:<EOL><INDENT>kwargs['<STR_LIT>'] = numeric_only<EOL><DEDENT>if '<STR_LIT>' not in kwargs:<EOL><INDENT>kwargs['<STR_LIT>'] = min_count<EOL><DEDENT>self._set_group_selection()<EOL>try:<EOL><INDENT>return self._cython_agg_general(<EOL>alias, alt=npfunc, **kwargs)<EOL><DEDENT>except AssertionError as e:<EOL><INDENT>raise SpecificationError(str(e))<EOL><DEDENT>except Exception:<EOL><INDENT>result = self.aggregate(<EOL>lambda x: npfunc(x, axis=self.axis))<EOL>if _convert:<EOL><INDENT>result = result._convert(datetime=True)<EOL><DEDENT>return result<EOL><DEDENT><DEDENT>set_function_name(f, name, cls)<EOL>return f<EOL><DEDENT>def first_compat(x, axis=<NUM_LIT:0>):<EOL><INDENT>def first(x):<EOL><INDENT>x = x.to_numpy()<EOL>x = x[notna(x)]<EOL>if len(x) == <NUM_LIT:0>:<EOL><INDENT>return np.nan<EOL><DEDENT>return x[<NUM_LIT:0>]<EOL><DEDENT>if isinstance(x, DataFrame):<EOL><INDENT>return x.apply(first, axis=axis)<EOL><DEDENT>else:<EOL><INDENT>return first(x)<EOL><DEDENT><DEDENT>def last_compat(x, axis=<NUM_LIT:0>):<EOL><INDENT>def last(x):<EOL><INDENT>x = x.to_numpy()<EOL>x = x[notna(x)]<EOL>if len(x) == <NUM_LIT:0>:<EOL><INDENT>return np.nan<EOL><DEDENT>return x[-<NUM_LIT:1>]<EOL><DEDENT>if isinstance(x, DataFrame):<EOL><INDENT>return x.apply(last, axis=axis)<EOL><DEDENT>else:<EOL><INDENT>return last(x)<EOL><DEDENT><DEDENT>cls.sum = groupby_function('<STR_LIT>', '<STR_LIT>', np.sum, min_count=<NUM_LIT:0>)<EOL>cls.prod = groupby_function('<STR_LIT>', '<STR_LIT>', np.prod, min_count=<NUM_LIT:0>)<EOL>cls.min = groupby_function('<STR_LIT>', '<STR_LIT>', np.min, numeric_only=False)<EOL>cls.max = groupby_function('<STR_LIT>', '<STR_LIT>', np.max, numeric_only=False)<EOL>cls.first = groupby_function('<STR_LIT>', '<STR_LIT>', first_compat,<EOL>numeric_only=False)<EOL>cls.last = groupby_function('<STR_LIT>', '<STR_LIT>', last_compat,<EOL>numeric_only=False)<EOL>
Add numeric operations to the GroupBy generically.