From 7b41917972418d6eb042040803fa34803b83dee7 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Tue, 6 Mar 2018 22:12:16 +0100 Subject: [PATCH 1/2] DOC/CLN: Index shared docs with appending actual docstrings --- pandas/core/indexes/base.py | 146 ++++++++++------------------ pandas/core/indexes/category.py | 35 +++---- pandas/core/indexes/datetimelike.py | 11 +-- pandas/core/indexes/datetimes.py | 4 +- pandas/core/indexes/interval.py | 27 ++--- pandas/core/indexes/multi.py | 29 +++--- pandas/core/indexes/numeric.py | 34 +++---- pandas/core/indexes/period.py | 13 +-- pandas/core/indexes/range.py | 8 +- pandas/core/indexes/timedeltas.py | 3 +- 10 files changed, 118 insertions(+), 192 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 0813c12d573d5..4f108b8eb399b 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -73,8 +73,7 @@ _index_doc_kwargs = dict(klass='Index', inplace='', target_klass='Index', - unique='Index', duplicated='np.ndarray') -_index_shared_docs = dict() + unique='Index') def _try_get_item(x): @@ -473,7 +472,8 @@ def _simple_new(cls, values, name=None, dtype=None, **kwargs): setattr(result, k, v) return result._reset_identity() - _index_shared_docs['_shallow_copy'] = """ + def _shallow_copy(self, values=None, **kwargs): + """ create a new Index with the same class as the caller, don't copy the data, use the same object attributes with passed in attributes taking precedence @@ -485,9 +485,6 @@ def _simple_new(cls, values, name=None, dtype=None, **kwargs): values : the values to create the new Index, optional kwargs : updates the default attributes for this Index """ - - @Appender(_index_shared_docs['_shallow_copy']) - def _shallow_copy(self, values=None, **kwargs): if values is None: values = self.values attributes = self._get_attributes_dict() @@ -554,7 +551,8 @@ def _sort_levels_monotonic(self): """ compat with MultiIndex """ return self - _index_shared_docs['_get_grouper_for_level'] = """ + def _get_grouper_for_level(self, mapper, level=None): + """ Get index grouper corresponding to an index level Parameters @@ -573,9 +571,6 @@ def _sort_levels_monotonic(self): uniques : Index or None Index of unique values for level """ - - @Appender(_index_shared_docs['_get_grouper_for_level']) - def _get_grouper_for_level(self, mapper, level=None): assert level is None or level == 0 if mapper is None: grouper = self @@ -706,7 +701,8 @@ def repeat(self, repeats, *args, **kwargs): nv.validate_repeat(args, kwargs) return self._shallow_copy(self._values.repeat(repeats)) - _index_shared_docs['where'] = """ + def where(self, cond, other=None): + """ .. versionadded:: 0.19.0 Return an Index of same shape as self and whose corresponding @@ -718,9 +714,6 @@ def repeat(self, repeats, *args, **kwargs): cond : boolean array-like with the same length as self other : scalar, or array-like """ - - @Appender(_index_shared_docs['where']) - def where(self, cond, other=None): if other is None: other = self._na_value @@ -856,7 +849,8 @@ def _coerce_scalar_to_index(self, item): return Index([item], dtype=dtype, **self._get_attributes_dict()) - _index_shared_docs['copy'] = """ + def copy(self, name=None, deep=False, dtype=None, **kwargs): + """ Make a copy of this object. Name and dtype sets those attributes on the new object. @@ -875,9 +869,6 @@ def _coerce_scalar_to_index(self, item): In most cases, there should be no functional difference from using ``deep``, but if ``deep`` is passed it will attempt to deepcopy. """ - - @Appender(_index_shared_docs['copy']) - def copy(self, name=None, deep=False, dtype=None, **kwargs): if deep: new_index = self._shallow_copy(self._data.copy()) else: @@ -1144,7 +1135,8 @@ def _to_embed(self, keep_tz=False, dtype=None): return self.values.copy() - _index_shared_docs['astype'] = """ + def astype(self, dtype, copy=True): + """ Create an Index with values cast to dtypes. The class of a new Index is determined by dtype. When conversion is impossible, a ValueError exception is raised. @@ -1161,9 +1153,6 @@ def _to_embed(self, keep_tz=False, dtype=None): .. versionadded:: 0.19.0 """ - - @Appender(_index_shared_docs['astype']) - def astype(self, dtype, copy=True): if is_dtype_equal(self.dtype, dtype): return self.copy() if copy else self elif is_categorical_dtype(dtype): @@ -1437,17 +1426,15 @@ def is_mixed(self): def holds_integer(self): return self.inferred_type in ['integer', 'mixed-integer'] - _index_shared_docs['_convert_scalar_indexer'] = """ + def _convert_scalar_indexer(self, key, kind=None): + """ Convert a scalar indexer. Parameters ---------- key : label of the slice bound kind : {'ix', 'loc', 'getitem', 'iloc'} or None - """ - - @Appender(_index_shared_docs['_convert_scalar_indexer']) - def _convert_scalar_indexer(self, key, kind=None): + """ assert kind in ['ix', 'loc', 'getitem', 'iloc', None] if kind == 'iloc': @@ -1482,7 +1469,8 @@ def _convert_scalar_indexer(self, key, kind=None): return key - _index_shared_docs['_convert_slice_indexer'] = """ + def _convert_slice_indexer(self, key, kind=None): + """ Convert a slice indexer. By definition, these are labels unless 'iloc' is passed in. @@ -1492,10 +1480,7 @@ def _convert_scalar_indexer(self, key, kind=None): ---------- key : label of the slice bound kind : {'ix', 'loc', 'getitem', 'iloc'} or None - """ - - @Appender(_index_shared_docs['_convert_slice_indexer']) - def _convert_slice_indexer(self, key, kind=None): + """ assert kind in ['ix', 'loc', 'getitem', 'iloc', None] # if we are not a slice, then we are done @@ -1583,7 +1568,8 @@ def _convert_listlike_indexer(self, keyarr, kind=None): indexer = self._convert_list_indexer(keyarr, kind=kind) return indexer, keyarr - _index_shared_docs['_convert_arr_indexer'] = """ + def _convert_arr_indexer(self, keyarr): + """ Convert an array-like indexer to the appropriate dtype. Parameters @@ -1594,14 +1580,12 @@ def _convert_listlike_indexer(self, keyarr, kind=None): Returns ------- converted_keyarr : array-like - """ - - @Appender(_index_shared_docs['_convert_arr_indexer']) - def _convert_arr_indexer(self, keyarr): + """ keyarr = com._asarray_tuplesafe(keyarr) return keyarr - _index_shared_docs['_convert_index_indexer'] = """ + def _convert_index_indexer(self, keyarr): + """ Convert an Index indexer to the appropriate dtype. Parameters @@ -1612,13 +1596,11 @@ def _convert_arr_indexer(self, keyarr): Returns ------- converted_keyarr : Index (or sub-class) - """ - - @Appender(_index_shared_docs['_convert_index_indexer']) - def _convert_index_indexer(self, keyarr): + """ return keyarr - _index_shared_docs['_convert_list_indexer'] = """ + def _convert_list_indexer(self, keyarr, kind=None): + """ Convert a list-like indexer to the appropriate dtype. Parameters @@ -1630,10 +1612,7 @@ def _convert_index_indexer(self, keyarr): Returns ------- positional indexer or None - """ - - @Appender(_index_shared_docs['_convert_list_indexer']) - def _convert_list_indexer(self, keyarr, kind=None): + """ if (kind in [None, 'iloc', 'ix'] and is_integer_dtype(keyarr) and not self.is_floating() and not isinstance(keyarr, ABCPeriodIndex)): @@ -1766,7 +1745,8 @@ def __nonzero__(self): __bool__ = __nonzero__ - _index_shared_docs['__contains__'] = """ + def __contains__(self, key): + """ return a boolean if this key is IN the index Parameters @@ -1777,16 +1757,14 @@ def __nonzero__(self): ------- boolean """ - - @Appender(_index_shared_docs['__contains__'] % _index_doc_kwargs) - def __contains__(self, key): hash(key) try: return key in self._engine except (OverflowError, TypeError, ValueError): return False - _index_shared_docs['contains'] = """ + def contains(self, key): + """ return a boolean if this key is IN the index Parameters @@ -1797,9 +1775,6 @@ def __contains__(self, key): ------- boolean """ - - @Appender(_index_shared_docs['contains'] % _index_doc_kwargs) - def contains(self, key): hash(key) try: return key in self._engine @@ -1890,7 +1865,9 @@ def _concat_same_dtype(self, to_concat, name): # must be overridden in specific classes return _concat._concat_index_asobject(to_concat, name) - _index_shared_docs['take'] = """ + def take(self, indices, axis=0, allow_fill=True, + fill_value=None, **kwargs): + """ return a new %(klass)s of the values selected by the indices For internal compatibility with numpy arrays. @@ -1910,10 +1887,6 @@ def _concat_same_dtype(self, to_concat, name): -------- numpy.ndarray.take """ - - @Appender(_index_shared_docs['take'] % _index_doc_kwargs) - def take(self, indices, axis=0, allow_fill=True, - fill_value=None, **kwargs): if kwargs: nv.validate_take(tuple(), kwargs) indices = _ensure_platform_int(indices) @@ -2582,7 +2555,8 @@ def _get_unique_index(self, dropna=False): return self._shallow_copy(values) - _index_shared_docs['get_loc'] = """ + def get_loc(self, key, method=None, tolerance=None): + """ Get integer location, slice or boolean mask for requested label. Parameters @@ -2625,9 +2599,6 @@ def _get_unique_index(self, dropna=False): >>> non_monotonic_index.get_loc('b') array([False, True, False, True], dtype=bool) """ - - @Appender(_index_shared_docs['get_loc']) - def get_loc(self, key, method=None, tolerance=None): if method is None: if tolerance is not None: raise ValueError('tolerance argument only valid if using pad, ' @@ -2726,7 +2697,8 @@ def _get_level_values(self, level): get_level_values = _get_level_values - _index_shared_docs['get_indexer'] = """ + def get_indexer(self, target, method=None, limit=None, tolerance=None): + """ Compute indexer and mask for new index given the current index. The indexer should be then used as an input to ndarray.take to align the current data to the new index. @@ -2768,9 +2740,6 @@ def _get_level_values(self, level): positions matches the corresponding target values. Missing values in the target are marked by -1. """ - - @Appender(_index_shared_docs['get_indexer'] % _index_doc_kwargs) - def get_indexer(self, target, method=None, limit=None, tolerance=None): method = missing.clean_reindex_fill_method(method) target = _ensure_index(target) if tolerance is not None: @@ -2891,7 +2860,8 @@ def _filter_indexer_tolerance(self, target, indexer, tolerance): indexer = np.where(distance <= tolerance, indexer, -1) return indexer - _index_shared_docs['get_indexer_non_unique'] = """ + def get_indexer_non_unique(self, target): + """ Compute indexer and mask for new index given the current index. The indexer should be then used as an input to ndarray.take to align the current data to the new index. @@ -2910,9 +2880,6 @@ def _filter_indexer_tolerance(self, target, indexer, tolerance): An indexer into the target of the values not found. These correspond to the -1 in the indexer array """ - - @Appender(_index_shared_docs['get_indexer_non_unique'] % _index_doc_kwargs) - def get_indexer_non_unique(self, target): target = _ensure_index(target) pself, ptarget = self._maybe_promote(target) if pself is not self or ptarget is not target: @@ -3189,7 +3156,9 @@ def _reindex_non_unique(self, target): new_index = self._shallow_copy_with_infer(new_labels, freq=None) return new_index, indexer, new_indexer - _index_shared_docs['join'] = """ + def join(self, other, how='left', level=None, return_indexers=False, + sort=False): + """ *this is an internal non-public method* Compute join_index and indexers to conform data @@ -3211,10 +3180,6 @@ def _reindex_non_unique(self, target): ------- join_index, (left_indexer, right_indexer) """ - - @Appender(_index_shared_docs['join']) - def join(self, other, how='left', level=None, return_indexers=False, - sort=False): from .multi import MultiIndex self_is_mi = isinstance(self, MultiIndex) other_is_mi = isinstance(other, MultiIndex) @@ -3641,7 +3606,8 @@ def _validate_indexer(self, form, key, kind): self._invalid_indexer(form, key) return key - _index_shared_docs['_maybe_cast_slice_bound'] = """ + def _maybe_cast_slice_bound(self, label, side, kind): + """ This function should be overloaded in subclasses that allow non-trivial casting on label-slice bounds, e.g. datetime-like indices allowing strings containing formatted datetimes. @@ -3661,9 +3627,6 @@ def _validate_indexer(self, form, key, kind): Value of `side` parameter should be validated in caller. """ - - @Appender(_index_shared_docs['_maybe_cast_slice_bound']) - def _maybe_cast_slice_bound(self, label, side, kind): assert kind in ['ix', 'loc', 'getitem', None] # We are a plain index here (sub-class override this method if they @@ -3901,7 +3864,7 @@ def drop(self, labels, errors='raise'): indexer = indexer[~mask] return self.delete(indexer) - _index_shared_docs['index_unique'] = ( + def unique(self, level=None): """ Return unique values in the index. Uniques are returned in order of appearance, this does NOT sort. @@ -3921,10 +3884,7 @@ def drop(self, labels, errors='raise'): -------- unique Series.unique - """) - - @Appender(_index_shared_docs['index_unique'] % _index_doc_kwargs) - def unique(self, level=None): + """ if level is not None: self._validate_index_level(level) result = super(Index, self).unique() @@ -3934,11 +3894,12 @@ def unique(self, level=None): def drop_duplicates(self, keep='first'): return super(Index, self).drop_duplicates(keep=keep) - @Appender(base._shared_docs['duplicated'] % _index_doc_kwargs) + @Appender(base._shared_docs['duplicated'] % dict(duplicated='np.ndarray')) def duplicated(self, keep='first'): return super(Index, self).duplicated(keep=keep) - _index_shared_docs['fillna'] = """ + def fillna(self, value=None, downcast=None): + """ Fill NA/NaN values with the specified value Parameters @@ -3955,9 +3916,6 @@ def duplicated(self, keep='first'): ------- filled : %(klass)s """ - - @Appender(_index_shared_docs['fillna']) - def fillna(self, value=None, downcast=None): self._assert_can_do_op(value) if self.hasnans: result = self.putmask(self._isnan, value) @@ -3967,7 +3925,8 @@ def fillna(self, value=None, downcast=None): return Index(result, name=self.name) return self._shallow_copy() - _index_shared_docs['dropna'] = """ + def dropna(self, how='any'): + """ Return Index without NA/NaN values Parameters @@ -3980,9 +3939,6 @@ def fillna(self, value=None, downcast=None): ------- valid : Index """ - - @Appender(_index_shared_docs['dropna']) - def dropna(self, how='any'): if how not in ('any', 'all'): raise ValueError("invalid how option: {0}".format(how)) diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index 218851b1713f2..acda100228f86 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -19,16 +19,13 @@ from pandas.util._decorators import Appender, cache_readonly from pandas.core.config import get_option -from pandas.core.indexes.base import Index, _index_shared_docs +from pandas.core.indexes.base import Index from pandas.core import accessor import pandas.core.common as com import pandas.core.base as base import pandas.core.missing as missing import pandas.core.indexes.base as ibase -_index_doc_kwargs = dict(ibase._index_doc_kwargs) -_index_doc_kwargs.update(dict(target_klass='CategoricalIndex')) - class CategoricalIndex(Index, accessor.PandasDelegate): """ @@ -191,7 +188,7 @@ def _simple_new(cls, values, name=None, categories=None, ordered=None, result._reset_identity() return result - @Appender(_index_shared_docs['_shallow_copy']) + @Appender(Index._shallow_copy.__doc__) def _shallow_copy(self, values=None, categories=None, ordered=None, dtype=None, **kwargs): # categories and ordered can't be part of attributes, @@ -322,7 +319,7 @@ def ordered(self): def _reverse_indexer(self): return self._data._reverse_indexer() - @Appender(_index_shared_docs['__contains__'] % _index_doc_kwargs) + @Appender(Index.__contains__.__doc__) def __contains__(self, key): hash(key) @@ -331,7 +328,7 @@ def __contains__(self, key): return key in self.values - @Appender(_index_shared_docs['contains'] % _index_doc_kwargs) + @Appender(Index.contains.__doc__) def contains(self, key): hash(key) @@ -344,7 +341,7 @@ def __array__(self, dtype=None): """ the array interface, return my values """ return np.array(self._data, dtype=dtype) - @Appender(_index_shared_docs['astype']) + @Appender(Index.astype.__doc__) def astype(self, dtype, copy=True): if is_interval_dtype(dtype): from pandas import IntervalIndex @@ -362,7 +359,7 @@ def _isnan(self): """ return if each value is nan""" return self._data.codes == -1 - @Appender(ibase._index_shared_docs['fillna']) + @Appender(Index.fillna.__doc__) def fillna(self, value, downcast=None): self._assert_can_do_op(value) return CategoricalIndex(self._data.fillna(value), name=self.name) @@ -389,7 +386,7 @@ def is_monotonic_increasing(self): def is_monotonic_decreasing(self): return Index(self.codes).is_monotonic_decreasing - @Appender(_index_shared_docs['index_unique'] % _index_doc_kwargs) + @Appender(Index.unique.__doc__) def unique(self, level=None): if level is not None: self._validate_index_level(level) @@ -399,7 +396,7 @@ def unique(self, level=None): return self._shallow_copy(result, categories=result.categories, ordered=result.ordered) - @Appender(base._shared_docs['duplicated'] % _index_doc_kwargs) + @Appender(Index.duplicated.__doc__) def duplicated(self, keep='first'): from pandas._libs.hashtable import duplicated_int64 codes = self.codes.astype('i8') @@ -462,7 +459,7 @@ def _can_reindex(self, indexer): """ always allow reindexing """ pass - @Appender(_index_shared_docs['where']) + @Appender(Index.where.__doc__) def where(self, cond, other=None): if other is None: other = self._na_value @@ -558,7 +555,7 @@ def _reindex_non_unique(self, target): return new_target, indexer, new_indexer - @Appender(_index_shared_docs['get_indexer'] % _index_doc_kwargs) + @Appender(Index.get_indexer.__doc__) def get_indexer(self, target, method=None, limit=None, tolerance=None): from pandas.core.arrays.categorical import _recode_for_categories @@ -594,7 +591,7 @@ def get_indexer(self, target, method=None, limit=None, tolerance=None): indexer, _ = self._engine.get_indexer_non_unique(codes) return _ensure_platform_int(indexer) - @Appender(_index_shared_docs['get_indexer_non_unique'] % _index_doc_kwargs) + @Appender(Index.get_indexer_non_unique.__doc__) def get_indexer_non_unique(self, target): target = ibase._ensure_index(target) @@ -605,7 +602,7 @@ def get_indexer_non_unique(self, target): indexer, missing = self._engine.get_indexer_non_unique(codes) return _ensure_platform_int(indexer), missing - @Appender(_index_shared_docs['_convert_scalar_indexer']) + @Appender(Index._convert_scalar_indexer.__doc__) def _convert_scalar_indexer(self, key, kind=None): if self.categories._defer_to_indexing: return self.categories._convert_scalar_indexer(key, kind=kind) @@ -613,7 +610,7 @@ def _convert_scalar_indexer(self, key, kind=None): return super(CategoricalIndex, self)._convert_scalar_indexer( key, kind=kind) - @Appender(_index_shared_docs['_convert_list_indexer']) + @Appender(Index._convert_list_indexer.__doc__) def _convert_list_indexer(self, keyarr, kind=None): # Return our indexer or raise if all of the values are not included in # the categories @@ -631,7 +628,7 @@ def _convert_list_indexer(self, keyarr, kind=None): return self.get_indexer(keyarr) - @Appender(_index_shared_docs['_convert_arr_indexer']) + @Appender(Index._convert_arr_indexer.__doc__) def _convert_arr_indexer(self, keyarr): keyarr = com._asarray_tuplesafe(keyarr) @@ -640,11 +637,11 @@ def _convert_arr_indexer(self, keyarr): return self._shallow_copy(keyarr) - @Appender(_index_shared_docs['_convert_index_indexer']) + @Appender(Index._convert_index_indexer.__doc__) def _convert_index_indexer(self, keyarr): return self._shallow_copy(keyarr) - @Appender(_index_shared_docs['take'] % _index_doc_kwargs) + @Appender(Index.take.__doc__) def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs): nv.validate_take(tuple(), kwargs) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index e673bfe411cb4..3bcdac00776b8 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -44,15 +44,12 @@ from pandas.errors import NullFrequencyError, PerformanceWarning import pandas.io.formats.printing as printing -from pandas.core.indexes.base import Index, _index_shared_docs +from pandas.core.indexes.base import Index from pandas.util._decorators import Appender, cache_readonly import pandas.core.dtypes.concat as _concat import pandas.tseries.frequencies as frequencies from pandas.tseries.offsets import Tick, DateOffset -import pandas.core.indexes.base as ibase -_index_doc_kwargs = dict(ibase._index_doc_kwargs) - class DatelikeOps(object): """ common ops for DatetimeIndex/PeriodIndex, but not TimedeltaIndex """ @@ -256,7 +253,7 @@ def _box_values_as_index(self): def _format_with_header(self, header, **kwargs): return header + list(self._format_native_types(**kwargs)) - @Appender(_index_shared_docs['__contains__'] % _index_doc_kwargs) + @Appender(Index.__contains__.__doc__) def __contains__(self, key): try: res = self.get_loc(key) @@ -400,7 +397,7 @@ def sort_values(self, return_indexer=False, ascending=True): return self._simple_new(sorted_values, **attribs) - @Appender(_index_shared_docs['take'] % _index_doc_kwargs) + @Appender(Index.take.__doc__) def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs): nv.validate_take(tuple(), kwargs) @@ -953,7 +950,7 @@ def repeat(self, repeats, *args, **kwargs): return self._shallow_copy(self.asi8.repeat(repeats), freq=freq) - @Appender(_index_shared_docs['where'] % _index_doc_kwargs) + @Appender(Index.where.__doc__) def where(self, cond, other=None): other = _ensure_datetimelike_to_i8(other) values = _ensure_datetimelike_to_i8(self) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index e5e9bba269fd4..1a25e6c3f375a 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -36,7 +36,7 @@ from pandas.errors import PerformanceWarning from pandas.core.algorithms import checked_add_with_arr -from pandas.core.indexes.base import Index, _index_shared_docs +from pandas.core.indexes.base import Index from pandas.core.indexes.numeric import Int64Index, Float64Index import pandas.compat as compat from pandas.tseries.frequencies import to_offset, get_period_alias, Resolution @@ -968,7 +968,7 @@ def _format_native_types(self, na_rep='NaT', date_format=None, **kwargs): format=format, na_rep=na_rep) - @Appender(_index_shared_docs['astype']) + @Appender(Index.astype.__doc__) def astype(self, dtype, copy=True): dtype = pandas_dtype(dtype) if (is_datetime64_ns_dtype(dtype) and diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index d431ea1e51e31..8ddcede2cef3a 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -24,8 +24,7 @@ is_integer, pandas_dtype) from pandas.core.indexes.base import ( - Index, _ensure_index, - default_pprint, _index_shared_docs) + Index, _ensure_index, default_pprint) from pandas._libs import Timestamp, Timedelta from pandas._libs.interval import ( @@ -42,12 +41,6 @@ from pandas.tseries.frequencies import to_offset from pandas.tseries.offsets import DateOffset -import pandas.core.indexes.base as ibase -_index_doc_kwargs = dict(ibase._index_doc_kwargs) -_index_doc_kwargs.update( - dict(klass='IntervalIndex', - target_klass='IntervalIndex or list of Intervals')) - _VALID_CLOSED = set(['left', 'right', 'both', 'neither']) @@ -302,7 +295,7 @@ def _simple_new(cls, left, right, closed=None, name=None, copy=False, result._reset_identity() return result - @Appender(_index_shared_docs['_shallow_copy']) + @Appender(Index._shallow_copy.__doc__) def _shallow_copy(self, left=None, right=None, **kwargs): if left is None: @@ -729,7 +722,7 @@ def __reduce__(self): d.update(self._get_attributes_dict()) return _new_IntervalIndex, (self.__class__, d), None - @Appender(_index_shared_docs['copy']) + @Appender(Index.copy.__doc__) def copy(self, deep=False, name=None): left = self.left.copy(deep=True) if deep else self.left right = self.right.copy(deep=True) if deep else self.right @@ -737,7 +730,7 @@ def copy(self, deep=False, name=None): closed = self.closed return type(self).from_arrays(left, right, closed=closed, name=name) - @Appender(_index_shared_docs['astype']) + @Appender(Index.astype.__doc__) def astype(self, dtype, copy=True): dtype = pandas_dtype(dtype) if is_interval_dtype(dtype) and dtype != self.dtype: @@ -832,7 +825,7 @@ def is_non_overlapping_monotonic(self): return bool((self.right[:-1] <= self.left[1:]).all() or (self.left[:-1] >= self.right[1:]).all()) - @Appender(_index_shared_docs['_convert_scalar_indexer']) + @Appender(Index._convert_scalar_indexer.__doc__) def _convert_scalar_indexer(self, key, kind=None): if kind == 'iloc': return super(IntervalIndex, self)._convert_scalar_indexer( @@ -842,7 +835,7 @@ def _convert_scalar_indexer(self, key, kind=None): def _maybe_cast_slice_bound(self, label, side, kind): return getattr(self, side)._maybe_cast_slice_bound(label, side, kind) - @Appender(_index_shared_docs['_convert_list_indexer']) + @Appender(Index._convert_list_indexer.__doc__) def _convert_list_indexer(self, keyarr, kind=None): """ we are passed a list-like indexer. Return the @@ -1034,7 +1027,7 @@ def get_value(self, series, key): loc = self.get_loc(key) return series.iloc[loc] - @Appender(_index_shared_docs['get_indexer'] % _index_doc_kwargs) + @Appender(Index.get_indexer.__doc__) def get_indexer(self, target, method=None, limit=None, tolerance=None): self._check_method(method) @@ -1135,12 +1128,12 @@ def _get_reindexer(self, target): return np.concatenate(indexer) - @Appender(_index_shared_docs['get_indexer_non_unique'] % _index_doc_kwargs) + @Appender(Index.get_indexer_non_unique.__doc__) def get_indexer_non_unique(self, target): target = self._maybe_cast_indexed(_ensure_index(target)) return super(IntervalIndex, self).get_indexer_non_unique(target) - @Appender(_index_shared_docs['where']) + @Appender(Index.where.__doc__) def where(self, cond, other=None): if other is None: other = self._na_value @@ -1215,7 +1208,7 @@ def _concat_same_dtype(self, to_concat, name): raise ValueError(msg) return super(IntervalIndex, self)._concat_same_dtype(to_concat, name) - @Appender(_index_shared_docs['take'] % _index_doc_kwargs) + @Appender(Index.take.__doc__) def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs): nv.validate_take(tuple(), kwargs) diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 73f4aee1c4880..eec998d585106 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -23,7 +23,6 @@ from pandas.core.dtypes.missing import isna, array_equivalent from pandas.errors import PerformanceWarning, UnsortedIndexError -import pandas.core.base as base from pandas.util._decorators import Appender, cache_readonly, deprecate_kwarg import pandas.core.common as com import pandas.core.missing as missing @@ -33,16 +32,10 @@ from pandas.core.config import get_option from pandas.core.indexes.base import ( - Index, _ensure_index, - InvalidIndexError, - _index_shared_docs) + Index, _ensure_index, InvalidIndexError) from pandas.core.indexes.frozen import ( FrozenNDArray, FrozenList, _ensure_frozen) import pandas.core.indexes.base as ibase -_index_doc_kwargs = dict(ibase._index_doc_kwargs) -_index_doc_kwargs.update( - dict(klass='MultiIndex', - target_klass='MultiIndex or list of tuples')) class MultiIndexUIntEngine(libindex.BaseMultiIndexCodesEngine, @@ -540,7 +533,7 @@ def _shallow_copy_with_infer(self, values=None, **kwargs): **kwargs) return self._shallow_copy(values, **kwargs) - @Appender(_index_shared_docs['__contains__'] % _index_doc_kwargs) + @Appender(Index.__contains__.__doc__) def __contains__(self, key): hash(key) try: @@ -551,7 +544,7 @@ def __contains__(self, key): contains = __contains__ - @Appender(_index_shared_docs['_shallow_copy']) + @Appender(Index._shallow_copy.__doc__) def _shallow_copy(self, values=None, **kwargs): if values is not None: if 'name' in kwargs: @@ -697,7 +690,7 @@ def _format_native_types(self, na_rep='nan', **kwargs): return mi.values - @Appender(_index_shared_docs['_get_grouper_for_level']) + @Appender(Index._get_grouper_for_level.__doc__) def _get_grouper_for_level(self, mapper, level): indexer = self.labels[level] level_index = self.levels[level] @@ -916,7 +909,7 @@ def f(k, stringify): for k, stringify in zip(key, self._have_mixed_levels)]) return hash_tuple(key) - @Appender(base._shared_docs['duplicated'] % _index_doc_kwargs) + @Appender(Index.duplicated.__doc__) def duplicated(self, keep='first'): from pandas.core.sorting import get_group_index from pandas._libs.hashtable import duplicated_int64 @@ -932,7 +925,7 @@ def fillna(self, value=None, downcast=None): """ raise NotImplementedError('isna is not defined for MultiIndex') - @Appender(_index_shared_docs['dropna']) + @Appender(Index.dropna.__doc__) def dropna(self, how='any'): nans = [label == -1 for label in self.labels] if how == 'any': @@ -1067,7 +1060,7 @@ def get_level_values(self, level): values = self._get_level_values(level) return values - @Appender(_index_shared_docs['index_unique'] % _index_doc_kwargs) + @Appender(Index.unique.__doc__) def unique(self, level=None): if level is None: @@ -1577,7 +1570,7 @@ def __getitem__(self, key): names=self.names, sortorder=sortorder, verify_integrity=False) - @Appender(_index_shared_docs['take'] % _index_doc_kwargs) + @Appender(Index.take.__doc__) def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs): nv.validate_take(tuple(), kwargs) @@ -1948,7 +1941,7 @@ def _convert_listlike_indexer(self, keyarr, kind=None): return indexer, keyarr - @Appender(_index_shared_docs['get_indexer'] % _index_doc_kwargs) + @Appender(Index.get_indexer.__doc__) def get_indexer(self, target, method=None, limit=None, tolerance=None): method = missing.clean_reindex_fill_method(method) target = _ensure_index(target) @@ -1986,7 +1979,7 @@ def get_indexer(self, target, method=None, limit=None, tolerance=None): return _ensure_platform_int(indexer) - @Appender(_index_shared_docs['get_indexer_non_unique'] % _index_doc_kwargs) + @Appender(Index.get_indexer_non_unique.__doc__) def get_indexer_non_unique(self, target): return super(MultiIndex, self).get_indexer_non_unique(target) @@ -2770,7 +2763,7 @@ def difference(self, other): return MultiIndex.from_tuples(difference, sortorder=0, names=result_names) - @Appender(_index_shared_docs['astype']) + @Appender(Index.astype.__doc__) def astype(self, dtype, copy=True): dtype = pandas_dtype(dtype) if is_categorical_dtype(dtype): diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index 1fe0c8fa289e6..ca322b02df803 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -13,16 +13,12 @@ from pandas import compat from pandas.core import algorithms import pandas.core.common as com -from pandas.core.indexes.base import ( - Index, InvalidIndexError, _index_shared_docs) +from pandas.core.indexes.base import Index, InvalidIndexError from pandas.util._decorators import Appender, cache_readonly import pandas.core.dtypes.concat as _concat import pandas.core.indexes.base as ibase -_num_index_shared_docs = dict() - - class NumericIndex(Index): """ Provide numeric type operations @@ -54,14 +50,14 @@ def __new__(cls, data=None, dtype=None, copy=False, name=None, name = data.name return cls._simple_new(subarr, name=name) - @Appender(_index_shared_docs['_maybe_cast_slice_bound']) + @Appender(Index._maybe_cast_slice_bound.__doc__) def _maybe_cast_slice_bound(self, label, side, kind): assert kind in ['ix', 'loc', 'getitem', None] # we will try to coerce to integers return self._maybe_cast_indexer(label) - @Appender(_index_shared_docs['_shallow_copy']) + @Appender(Index._shallow_copy.__doc__) def _shallow_copy(self, values=None, **kwargs): if values is not None and not self._can_hold_na: # Ensure we are not returning an Int64Index with float data: @@ -115,7 +111,7 @@ def is_all_dates(self): return False -_num_index_shared_docs['class_descr'] = """ +_num_index_shared_docs = """ Immutable ndarray implementing an ordered, sliceable set. The basic object storing axis labels for all pandas objects. %(klass)s is a special case of `Index` with purely %(ltype)s labels. %(extra)s @@ -155,7 +151,7 @@ def is_all_dates(self): class Int64Index(NumericIndex): - __doc__ = _num_index_shared_docs['class_descr'] % _int64_descr_args + __doc__ = _num_index_shared_docs % _int64_descr_args _typ = 'int64index' _left_indexer_unique = libjoin.left_join_indexer_unique_int64 @@ -176,7 +172,7 @@ def asi8(self): # do not cache or you'll create a memory leak return self.values.view('i8') - @Appender(_index_shared_docs['_convert_scalar_indexer']) + @Appender(Index._convert_scalar_indexer.__doc__) def _convert_scalar_indexer(self, key, kind=None): assert kind in ['ix', 'loc', 'getitem', 'iloc', None] @@ -213,7 +209,7 @@ def _assert_safe_casting(cls, data, subarr): class UInt64Index(NumericIndex): - __doc__ = _num_index_shared_docs['class_descr'] % _uint64_descr_args + __doc__ = _num_index_shared_docs % _uint64_descr_args _typ = 'uint64index' _left_indexer_unique = libjoin.left_join_indexer_unique_uint64 @@ -234,7 +230,7 @@ def asi8(self): # do not cache or you'll create a memory leak return self.values.view('u8') - @Appender(_index_shared_docs['_convert_scalar_indexer']) + @Appender(Index._convert_scalar_indexer.__doc__) def _convert_scalar_indexer(self, key, kind=None): assert kind in ['ix', 'loc', 'getitem', 'iloc', None] @@ -244,7 +240,7 @@ def _convert_scalar_indexer(self, key, kind=None): return (super(UInt64Index, self) ._convert_scalar_indexer(key, kind=kind)) - @Appender(_index_shared_docs['_convert_arr_indexer']) + @Appender(Index._convert_arr_indexer.__doc__) def _convert_arr_indexer(self, keyarr): # Cast the indexer to uint64 if possible so # that the values returned from indexing are @@ -254,7 +250,7 @@ def _convert_arr_indexer(self, keyarr): return com._asarray_tuplesafe(keyarr, dtype=np.uint64) return keyarr - @Appender(_index_shared_docs['_convert_index_indexer']) + @Appender(Index._convert_index_indexer.__doc__) def _convert_index_indexer(self, keyarr): # Cast the indexer to uint64 if possible so # that the values returned from indexing are @@ -290,7 +286,7 @@ def _assert_safe_casting(cls, data, subarr): class Float64Index(NumericIndex): - __doc__ = _num_index_shared_docs['class_descr'] % _float64_descr_args + __doc__ = _num_index_shared_docs % _float64_descr_args _typ = 'float64index' _engine_type = libindex.Float64Engine @@ -306,7 +302,7 @@ def inferred_type(self): """Always 'floating' for ``Float64Index``""" return 'floating' - @Appender(_index_shared_docs['astype']) + @Appender(Index.astype.__doc__) def astype(self, dtype, copy=True): dtype = pandas_dtype(dtype) if needs_i8_conversion(dtype): @@ -318,7 +314,7 @@ def astype(self, dtype, copy=True): raise ValueError('Cannot convert NA to integer') return super(Float64Index, self).astype(dtype, copy=copy) - @Appender(_index_shared_docs['_convert_scalar_indexer']) + @Appender(Index._convert_scalar_indexer.__doc__) def _convert_scalar_indexer(self, key, kind=None): assert kind in ['ix', 'loc', 'getitem', 'iloc', None] @@ -327,7 +323,7 @@ def _convert_scalar_indexer(self, key, kind=None): return key - @Appender(_index_shared_docs['_convert_slice_indexer']) + @Appender(Index._convert_slice_indexer.__doc__) def _convert_slice_indexer(self, key, kind=None): # if we are not a slice, then we are done if not isinstance(key, slice): @@ -400,7 +396,7 @@ def __contains__(self, other): return False - @Appender(_index_shared_docs['get_loc']) + @Appender(Index.get_loc.__doc__) def get_loc(self, key, method=None, tolerance=None): try: if np.all(np.isnan(key)): diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index 97cb3fbd877dd..3e433bef18d24 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -37,18 +37,13 @@ from pandas._libs.tslibs.timedeltas import delta_to_nanoseconds from pandas.core.base import _shared_docs -from pandas.core.indexes.base import _index_shared_docs, _ensure_index +from pandas.core.indexes.base import Index, _ensure_index from pandas import compat from pandas.util._decorators import (Appender, Substitution, cache_readonly, deprecate_kwarg) from pandas.compat import zip, u -import pandas.core.indexes.base as ibase -_index_doc_kwargs = dict(ibase._index_doc_kwargs) -_index_doc_kwargs.update( - dict(target_klass='PeriodIndex or list of Periods')) - def _field_accessor(name, alias, docstring=None): def f(self): @@ -386,7 +381,7 @@ def _coerce_scalar_to_index(self, item): """ return PeriodIndex([item], **self._get_attributes_dict()) - @Appender(_index_shared_docs['__contains__']) + @Appender(Index.__contains__.__doc__) def __contains__(self, key): if isinstance(key, Period): if key.freq != self.freq: @@ -510,7 +505,7 @@ def asof_locs(self, where, mask): return result - @Appender(_index_shared_docs['astype']) + @Appender(Index.astype.__doc__) def astype(self, dtype, copy=True, how='start'): dtype = pandas_dtype(dtype) if is_integer_dtype(dtype): @@ -825,7 +820,7 @@ def get_value(self, series, key): return com._maybe_box(self, self._engine.get_value(s, key), series, key) - @Appender(_index_shared_docs['get_indexer'] % _index_doc_kwargs) + @Appender(Index.get_indexer.__doc__) def get_indexer(self, target, method=None, limit=None, tolerance=None): target = _ensure_index(target) diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index 7c266dc889368..6e03cda28c7af 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -17,7 +17,7 @@ import pandas.core.common as com from pandas.core import ops -from pandas.core.indexes.base import Index, _index_shared_docs +from pandas.core.indexes.base import Index from pandas.util._decorators import Appender, cache_readonly import pandas.core.dtypes.concat as _concat import pandas.core.indexes.base as ibase @@ -257,7 +257,7 @@ def has_duplicates(self): def tolist(self): return lrange(self._start, self._stop, self._step) - @Appender(_index_shared_docs['_shallow_copy']) + @Appender(Index._shallow_copy.__doc__) def _shallow_copy(self, values=None, **kwargs): if values is None: return RangeIndex(name=self.name, fastpath=True, @@ -266,7 +266,7 @@ def _shallow_copy(self, values=None, **kwargs): kwargs.setdefault('name', self.name) return self._int64index._shallow_copy(values, **kwargs) - @Appender(ibase._index_shared_docs['copy']) + @Appender(Index.copy.__doc__) def copy(self, name=None, deep=False, dtype=None, **kwargs): self._validate_dtype(dtype) if name is None: @@ -464,7 +464,7 @@ def union(self, other): return self._int64index.union(other) - @Appender(_index_shared_docs['join']) + @Appender(Index.join.__doc__) def join(self, other, how='left', level=None, return_indexers=False, sort=False): if how == 'outer' and self is not other: diff --git a/pandas/core/indexes/timedeltas.py b/pandas/core/indexes/timedeltas.py index a14de18b1012f..29713782b7c0c 100644 --- a/pandas/core/indexes/timedeltas.py +++ b/pandas/core/indexes/timedeltas.py @@ -24,7 +24,6 @@ from pandas.tseries.frequencies import to_offset from pandas.core.algorithms import checked_add_with_arr from pandas.core.base import _shared_docs -from pandas.core.indexes.base import _index_shared_docs import pandas.core.common as com import pandas.core.dtypes.concat as _concat from pandas.util._decorators import Appender, Substitution, deprecate_kwarg @@ -516,7 +515,7 @@ def to_pytimedelta(self): """ return libts.ints_to_pytimedelta(self.asi8) - @Appender(_index_shared_docs['astype']) + @Appender(Index.astype.__doc__) def astype(self, dtype, copy=True): dtype = pandas_dtype(dtype) if is_timedelta64_dtype(dtype) and not is_timedelta64_ns_dtype(dtype): From d5494d3f46212aed4862ac78a2652cd294839233 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Tue, 6 Mar 2018 22:21:43 +0100 Subject: [PATCH 2/2] hard code previously substituted values --- pandas/core/indexes/base.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 4f108b8eb399b..452c2f5e4a55a 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1868,7 +1868,7 @@ def _concat_same_dtype(self, to_concat, name): def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs): """ - return a new %(klass)s of the values selected by the indices + return a new Index of the values selected by the indices For internal compatibility with numpy arrays. @@ -2705,7 +2705,7 @@ def get_indexer(self, target, method=None, limit=None, tolerance=None): Parameters ---------- - target : %(target_klass)s + target : array-like or Index method : {None, 'pad'/'ffill', 'backfill'/'bfill', 'nearest'}, optional * default: exact matches only. * pad / ffill: find the PREVIOUS index value if no exact match. @@ -2868,7 +2868,7 @@ def get_indexer_non_unique(self, target): Parameters ---------- - target : %(target_klass)s + target : array-like or Index Returns ------- @@ -3914,7 +3914,7 @@ def fillna(self, value=None, downcast=None): Returns ------- - filled : %(klass)s + filled : Index of the same type """ self._assert_can_do_op(value) if self.hasnans: