diff --git a/ci/code_checks.sh b/ci/code_checks.sh index ac92cf492b91d..a8ca81bde9dcd 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -212,8 +212,8 @@ fi ### DOCSTRINGS ### if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then - MSG='Validate docstrings (GL09, GL06, SS04, PR03, PR05, EX04)' ; echo $MSG - $BASE_DIR/scripts/validate_docstrings.py --format=azure --errors=GL09,GL06,SS04,PR03,PR05,EX04 + MSG='Validate docstrings (GL06, GL07, GL09, SS04, PR03, PR05, EX04)' ; echo $MSG + $BASE_DIR/scripts/validate_docstrings.py --format=azure --errors=GL06,GL07,GL09,SS04,PR03,PR05,EX04 RET=$(($RET + $?)) ; echo $MSG "DONE" fi diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 6b74fd7e06de9..7b8cd71e64f25 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -6037,7 +6037,7 @@ def _gotitem(self, # TODO: _shallow_copy(subset)? return subset[key] - _agg_doc = dedent(""" + _agg_summary_and_see_also_doc = dedent(""" The aggregation operations are always performed over an axis, either the index (default) or the column axis. This behavior is different from `numpy` aggregation functions (`mean`, `median`, `prod`, `sum`, `std`, @@ -6047,6 +6047,19 @@ def _gotitem(self, `agg` is an alias for `aggregate`. Use the alias. + See Also + -------- + DataFrame.apply : Perform any type of operations. + DataFrame.transform : Perform transformation type operations. + pandas.core.groupby.GroupBy : Perform operations over groups. + pandas.core.resample.Resampler : Perform operations over resampled bins. + pandas.core.window.Rolling : Perform operations over rolling window. + pandas.core.window.Expanding : Perform operations over expanding window. + pandas.core.window.EWM : Perform operation over exponential weighted + window. + """) + + _agg_examples_doc = dedent(""" Examples -------- >>> df = pd.DataFrame([[1, 2, 3], @@ -6078,23 +6091,13 @@ def _gotitem(self, 2 8.0 3 NaN dtype: float64 - - See Also - -------- - DataFrame.apply : Perform any type of operations. - DataFrame.transform : Perform transformation type operations. - pandas.core.groupby.GroupBy : Perform operations over groups. - pandas.core.resample.Resampler : Perform operations over resampled bins. - pandas.core.window.Rolling : Perform operations over rolling window. - pandas.core.window.Expanding : Perform operations over expanding window. - pandas.core.window.EWM : Perform operation over exponential weighted - window. """) - @Appender(_agg_doc) - @Appender(_shared_docs['aggregate'] % dict( - versionadded='.. versionadded:: 0.20.0', - **_shared_doc_kwargs)) + @Substitution(see_also=_agg_summary_and_see_also_doc, + examples=_agg_examples_doc, + versionadded='.. versionadded:: 0.20.0', + **_shared_doc_kwargs) + @Appender(_shared_docs['aggregate']) def aggregate(self, func, axis=0, *args, **kwargs): axis = self._get_axis_number(axis) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 0df4a067dda44..6eb6bc124c80a 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4,6 +4,7 @@ import gc import json import operator +from textwrap import dedent import warnings import weakref @@ -4895,7 +4896,7 @@ def sample(self, n=None, frac=None, replace=False, weights=None, def pipe(self, func, *args, **kwargs): return com._pipe(self, func, *args, **kwargs) - _shared_docs['aggregate'] = (""" + _shared_docs['aggregate'] = dedent(""" Aggregate using one or more operations over the specified axis. %(versionadded)s @@ -4926,11 +4927,15 @@ def pipe(self, func, *args, **kwargs): if Series.agg is called with single function, returns a scalar if Series.agg is called with several functions, returns a Series + %(see_also)s + Notes ----- `agg` is an alias for `aggregate`. Use the alias. A passed user-defined-function will be passed a Series for evaluation. + + %(examples)s """) _shared_docs['transform'] = (""" diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index 47ac1260d5179..33a41ab1cabc4 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -706,10 +706,17 @@ def _selection_name(self): else: return self._selection - _agg_doc = dedent(""" - Examples + _agg_see_also_doc = dedent(""" + See Also -------- + pandas.Series.groupby.apply + pandas.Series.groupby.transform + pandas.Series.aggregate + """) + _agg_examples_doc = dedent(""" + Examples + -------- >>> s = pd.Series([1, 2, 3, 4]) >>> s @@ -733,13 +740,6 @@ def _selection_name(self): min max 1 1 2 2 3 4 - - See Also - -------- - pandas.Series.groupby.apply - pandas.Series.groupby.transform - pandas.Series.aggregate - """) @Appender(_apply_docs['template'] @@ -748,11 +748,12 @@ def _selection_name(self): def apply(self, func, *args, **kwargs): return super(SeriesGroupBy, self).apply(func, *args, **kwargs) - @Appender(_agg_doc) - @Appender(_shared_docs['aggregate'] % dict( - klass='Series', - versionadded='', - axis='')) + @Substitution(see_also=_agg_see_also_doc, + examples=_agg_examples_doc, + versionadded='', + klass='Series', + axis='') + @Appender(_shared_docs['aggregate']) def aggregate(self, func_or_funcs, *args, **kwargs): _level = kwargs.pop('_level', None) if isinstance(func_or_funcs, compat.string_types): @@ -1246,7 +1247,15 @@ class DataFrameGroupBy(NDFrameGroupBy): _block_agg_axis = 1 - _agg_doc = dedent(""" + _agg_see_also_doc = dedent(""" + See Also + -------- + pandas.DataFrame.groupby.apply + pandas.DataFrame.groupby.transform + pandas.DataFrame.aggregate + """) + + _agg_examples_doc = dedent(""" Examples -------- @@ -1294,19 +1303,14 @@ class DataFrameGroupBy(NDFrameGroupBy): A 1 1 2 0.590716 2 3 4 0.704907 - - See Also - -------- - pandas.DataFrame.groupby.apply - pandas.DataFrame.groupby.transform - pandas.DataFrame.aggregate """) - @Appender(_agg_doc) - @Appender(_shared_docs['aggregate'] % dict( - klass='DataFrame', - versionadded='', - axis='')) + @Substitution(see_also=_agg_see_also_doc, + examples=_agg_examples_doc, + versionadded='', + klass='DataFrame', + axis='') + @Appender(_shared_docs['aggregate']) def aggregate(self, arg, *args, **kwargs): return super(DataFrameGroupBy, self).aggregate(arg, *args, **kwargs) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index f8f3ea7f0e72a..f7c6ccdc25395 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -41,7 +41,7 @@ class providing the base-class of operations. from pandas.core.series import Series from pandas.core.sorting import get_group_index_sorter -_doc_template = """ +_common_see_also = """ See Also -------- pandas.Series.%(name)s @@ -1044,7 +1044,7 @@ def result_to_bool(result): val_test=val_test, skipna=skipna) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def any(self, skipna=True): """ Returns True if any value in the group is truthful, else False. @@ -1057,7 +1057,7 @@ def any(self, skipna=True): return self._bool_agg('any', skipna) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def all(self, skipna=True): """ Returns True if all values in the group are truthful, else False. @@ -1070,7 +1070,7 @@ def all(self, skipna=True): return self._bool_agg('all', skipna) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def count(self): """ Compute count of group, excluding missing values. @@ -1079,8 +1079,7 @@ def count(self): # defined here for API doc raise NotImplementedError - @Substitution(name='groupby') - @Appender(_doc_template) + @Substitution(name='groupby', see_also=_common_see_also) def mean(self, *args, **kwargs): """ Compute mean of groups, excluding missing values. @@ -1089,6 +1088,8 @@ def mean(self, *args, **kwargs): ------- pandas.Series or pandas.DataFrame + %(see_also)s + Examples -------- >>> df = pd.DataFrame({'A': [1, 1, 2, 1, 2], @@ -1137,7 +1138,7 @@ def mean(self, *args, **kwargs): return self._python_agg_general(f) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def median(self, **kwargs): """ Compute median of groups, excluding missing values. @@ -1158,7 +1159,7 @@ def f(x): return self._python_agg_general(f) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def std(self, ddof=1, *args, **kwargs): """ Compute standard deviation of groups, excluding missing values. @@ -1176,7 +1177,7 @@ def std(self, ddof=1, *args, **kwargs): return np.sqrt(self.var(ddof=ddof, **kwargs)) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def var(self, ddof=1, *args, **kwargs): """ Compute variance of groups, excluding missing values. @@ -1202,7 +1203,7 @@ def var(self, ddof=1, *args, **kwargs): return self._python_agg_general(f) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def sem(self, ddof=1): """ Compute standard error of the mean of groups, excluding missing values. @@ -1218,7 +1219,7 @@ def sem(self, ddof=1): return self.std(ddof=ddof) / np.sqrt(self.count()) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def size(self): """ Compute group sizes. @@ -1242,7 +1243,7 @@ def groupby_function(name, alias, npfunc, _local_template = "Compute %(f)s of group values" @Substitution(name='groupby', f=name) - @Appender(_doc_template) + @Appender(_common_see_also) @Appender(_local_template) def f(self, **kwargs): if 'numeric_only' not in kwargs: @@ -1307,7 +1308,7 @@ def last(x): numeric_only=False) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def ohlc(self): """ Compute sum of values, excluding missing values. @@ -1436,7 +1437,7 @@ def resample(self, rule, *args, **kwargs): return get_resampler_for_grouping(self, rule, *args, **kwargs) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def rolling(self, *args, **kwargs): """ Return a rolling grouper, providing rolling functionality per group. @@ -1445,7 +1446,7 @@ def rolling(self, *args, **kwargs): return RollingGroupby(self, *args, **kwargs) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def expanding(self, *args, **kwargs): """ Return an expanding grouper, providing expanding @@ -1527,8 +1528,7 @@ def backfill(self, limit=None): return self._fill('bfill', limit=limit) bfill = backfill - @Substitution(name='groupby') - @Appender(_doc_template) + @Substitution(name='groupby', see_also=_common_see_also) def nth(self, n, dropna=None): """ Take the nth row from each group if n is an int, or a subset of rows @@ -1547,6 +1547,8 @@ def nth(self, n, dropna=None): apply the specified dropna operation before counting which row is the nth row. Needs to be None, 'any' or 'all' + %(see_also)s + Examples -------- @@ -1808,7 +1810,7 @@ def cumcount(self, ascending=True): return Series(cumcounts, index) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def rank(self, method='average', ascending=True, na_option='keep', pct=False, axis=0): """ @@ -1845,7 +1847,7 @@ def rank(self, method='average', ascending=True, na_option='keep', na_option=na_option, pct=pct, axis=axis) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def cumprod(self, axis=0, *args, **kwargs): """ Cumulative product for each group. @@ -1858,7 +1860,7 @@ def cumprod(self, axis=0, *args, **kwargs): return self._cython_transform('cumprod', **kwargs) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def cumsum(self, axis=0, *args, **kwargs): """ Cumulative sum for each group. @@ -1871,7 +1873,7 @@ def cumsum(self, axis=0, *args, **kwargs): return self._cython_transform('cumsum', **kwargs) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def cummin(self, axis=0, **kwargs): """ Cumulative min for each group. @@ -1882,7 +1884,7 @@ def cummin(self, axis=0, **kwargs): return self._cython_transform('cummin', numeric_only=False) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def cummax(self, axis=0, **kwargs): """ Cumulative max for each group. @@ -1991,7 +1993,7 @@ def _get_cythonized_result(self, how, grouper, aggregate=False, return self._wrap_transformed_output(output) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def shift(self, periods=1, freq=None, axis=0): """ Shift each group by periods observations. @@ -2014,7 +2016,7 @@ def shift(self, periods=1, freq=None, axis=0): periods=periods) @Substitution(name='groupby') - @Appender(_doc_template) + @Appender(_common_see_also) def pct_change(self, periods=1, fill_method='pad', limit=None, freq=None, axis=0): """ @@ -2031,8 +2033,7 @@ def pct_change(self, periods=1, fill_method='pad', limit=None, freq=None, shifted = fill_grp.shift(periods=periods, freq=freq) return (filled / shifted) - 1 - @Substitution(name='groupby') - @Appender(_doc_template) + @Substitution(name='groupby', see_also=_common_see_also) def head(self, n=5): """ Returns first n rows of each group. @@ -2040,6 +2041,8 @@ def head(self, n=5): Essentially equivalent to ``.apply(lambda x: x.head(n))``, except ignores as_index flag. + %(see_also)s + Examples -------- @@ -2058,8 +2061,7 @@ def head(self, n=5): mask = self._cumcount_array() < n return self._selected_obj[mask] - @Substitution(name='groupby') - @Appender(_doc_template) + @Substitution(name='groupby', see_also=_common_see_also) def tail(self, n=5): """ Returns last n rows of each group. @@ -2067,6 +2069,8 @@ def tail(self, n=5): Essentially equivalent to ``.apply(lambda x: x.tail(n))``, except ignores as_index flag. + %(see_also)s + Examples -------- diff --git a/pandas/core/resample.py b/pandas/core/resample.py index 9920fcbcbd2b8..ef43da6d5f490 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -211,13 +211,15 @@ def _assure_grouper(self): def pipe(self, func, *args, **kwargs): return super(Resampler, self).pipe(func, *args, **kwargs) - _agg_doc = dedent(""" + _agg_see_also_doc = dedent(""" See Also -------- pandas.DataFrame.groupby.aggregate pandas.DataFrame.resample.transform pandas.DataFrame.aggregate + """) + _agg_examples_doc = dedent(""" Examples -------- >>> s = pd.Series([1,2,3,4,5], @@ -253,11 +255,12 @@ def pipe(self, func, *args, **kwargs): 2013-01-01 00:00:04 5 NaN """) - @Appender(_agg_doc) - @Appender(_shared_docs['aggregate'] % dict( - klass='DataFrame', - versionadded='', - axis='')) + @Substitution(see_also=_agg_see_also_doc, + examples=_agg_examples_doc, + versionadded='', + klass='DataFrame', + axis='') + @Appender(_shared_docs['aggregate']) def aggregate(self, func, *args, **kwargs): self._set_binner() diff --git a/pandas/core/series.py b/pandas/core/series.py index 9ba9cdc818a5e..773f2d17cf0fc 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -3275,16 +3275,16 @@ def _gotitem(self, key, ndim, subset=None): """ return self - _agg_doc = dedent(""" + _agg_see_also_doc = dedent(""" See Also -------- Series.apply : Invoke function on a Series. - Series.transform : Transform function producing - a Series with like indexes. + Series.transform : Transform function producing a Series with like indexes. + """) + _agg_examples_doc = dedent(""" Examples -------- - >>> s = pd.Series([1, 2, 3, 4]) >>> s 0 1 @@ -3302,10 +3302,11 @@ def _gotitem(self, key, ndim, subset=None): dtype: int64 """) - @Appender(_agg_doc) - @Appender(generic._shared_docs['aggregate'] % dict( - versionadded='.. versionadded:: 0.20.0', - **_shared_doc_kwargs)) + @Substitution(see_also=_agg_see_also_doc, + examples=_agg_examples_doc, + versionadded='.. versionadded:: 0.20.0', + **_shared_doc_kwargs) + @Appender(generic._shared_docs['aggregate']) def aggregate(self, func, axis=0, *args, **kwargs): # Validate the axis parameter self._get_axis_number(axis) diff --git a/pandas/core/window.py b/pandas/core/window.py index 7aa4b51e0f55a..f7c23172172ac 100644 --- a/pandas/core/window.py +++ b/pandas/core/window.py @@ -693,7 +693,14 @@ def f(arg, *args, **kwargs): return self._wrap_results(results, blocks, obj) - _agg_doc = dedent(""" + _agg_see_also_doc = dedent(""" + See Also + -------- + pandas.DataFrame.rolling.aggregate + pandas.DataFrame.aggregate + """) + + _agg_examples_doc = dedent(""" Examples -------- @@ -723,19 +730,14 @@ def f(arg, *args, **kwargs): 7 0.906020 1.283573 0.085482 8 -0.096361 0.818139 0.472290 9 0.070889 0.134399 -0.031308 - - See Also - -------- - pandas.DataFrame.rolling.aggregate - pandas.DataFrame.aggregate - """) - @Appender(_agg_doc) - @Appender(_shared_docs['aggregate'] % dict( - versionadded='', - klass='Series/DataFrame', - axis='')) + @Substitution(see_also=_agg_see_also_doc, + examples=_agg_examples_doc, + versionadded='', + klass='Series/DataFrame', + axis='') + @Appender(_shared_docs['aggregate']) def aggregate(self, arg, *args, **kwargs): result, how = self._aggregate(arg, *args, **kwargs) if result is None: @@ -1595,12 +1597,14 @@ def _validate_freq(self): "compatible with a datetimelike " "index".format(self.window)) - _agg_doc = dedent(""" + _agg_see_also_doc = dedent(""" See Also -------- pandas.Series.rolling pandas.DataFrame.rolling + """) + _agg_examples_doc = dedent(""" Examples -------- @@ -1645,11 +1649,12 @@ def _validate_freq(self): 9 0.212668 -1.647453 """) - @Appender(_agg_doc) - @Appender(_shared_docs['aggregate'] % dict( - versionadded='', - klass='Series/DataFrame', - axis='')) + @Substitution(see_also=_agg_see_also_doc, + examples=_agg_examples_doc, + versionadded='', + klass='Series/Dataframe', + axis='') + @Appender(_shared_docs['aggregate']) def aggregate(self, arg, *args, **kwargs): return super(Rolling, self).aggregate(arg, *args, **kwargs) @@ -1883,7 +1888,15 @@ def _get_window(self, other=None): other = self.min_periods or -1 return max(length, other) - _agg_doc = dedent(""" + _agg_see_also_doc = dedent(""" + See Also + -------- + pandas.DataFrame.expanding.aggregate + pandas.DataFrame.rolling.aggregate + pandas.DataFrame.aggregate + """) + + _agg_examples_doc = dedent(""" Examples -------- @@ -1913,19 +1926,14 @@ def _get_window(self, other=None): 7 0.680292 0.132049 0.548693 8 0.067236 0.948257 0.163353 9 -0.286980 0.618493 -0.694496 - - See Also - -------- - pandas.DataFrame.expanding.aggregate - pandas.DataFrame.rolling.aggregate - pandas.DataFrame.aggregate """) - @Appender(_agg_doc) - @Appender(_shared_docs['aggregate'] % dict( - versionadded='', - klass='Series/DataFrame', - axis='')) + @Substitution(see_also=_agg_see_also_doc, + examples=_agg_examples_doc, + versionadded='', + klass='Series/Dataframe', + axis='') + @Appender(_shared_docs['aggregate']) def aggregate(self, arg, *args, **kwargs): return super(Expanding, self).aggregate(arg, *args, **kwargs) @@ -2184,7 +2192,13 @@ def __init__(self, obj, com=None, span=None, halflife=None, alpha=None, def _constructor(self): return EWM - _agg_doc = dedent(""" + _agg_see_also_doc = dedent(""" + See Also + -------- + pandas.DataFrame.rolling.aggregate + """) + + _agg_examples_doc = dedent(""" Examples -------- @@ -2214,17 +2228,14 @@ def _constructor(self): 7 0.680292 0.132049 0.548693 8 0.067236 0.948257 0.163353 9 -0.286980 0.618493 -0.694496 - - See Also - -------- - pandas.DataFrame.rolling.aggregate """) - @Appender(_agg_doc) - @Appender(_shared_docs['aggregate'] % dict( - versionadded='', - klass='Series/DataFrame', - axis='')) + @Substitution(see_also=_agg_see_also_doc, + examples=_agg_examples_doc, + versionadded='', + klass='Series/Dataframe', + axis='') + @Appender(_shared_docs['aggregate']) def aggregate(self, arg, *args, **kwargs): return super(EWM, self).aggregate(arg, *args, **kwargs)