Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardize function signatures #14645

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/source/whatsnew/v0.20.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ Other API Changes
Deprecations
^^^^^^^^^^^^

- ``Series.repeat()`` has deprecated the ``reps`` parameter in favor of ``repeats`` (:issue:`12662`)
- ``Index.repeat()`` and ``MultiIndex.repeat()`` have deprecated the ``n`` parameter in favor of ``repeats`` (:issue:`12662`)
- ``Categorical.searchsorted()`` and ``Series.searchsorted()`` have deprecated the ``v`` parameter in favor of ``value`` (:issue:`12662`)
- ``TimedeltaIndex.searchsorted()``, ``DatetimeIndex.searchsorted()``, and ``PeriodIndex.searchsorted()`` have deprecated the ``key`` parameter in favor of ``value`` (:issue:`12662`)



Expand Down
15 changes: 8 additions & 7 deletions pandas/core/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1091,12 +1091,12 @@ def factorize(self, sort=False, na_sentinel=-1):
"""Find indices where elements should be inserted to maintain order.

Find the indices into a sorted %(klass)s `self` such that, if the
corresponding elements in `v` were inserted before the indices, the
order of `self` would be preserved.
corresponding elements in `value` were inserted before the indices,
the order of `self` would be preserved.

Parameters
----------
%(value)s : array_like
value : array_like
Values to insert into `self`.
side : {'left', 'right'}, optional
If 'left', the index of the first suitable location found is given.
Expand All @@ -1109,7 +1109,7 @@ def factorize(self, sort=False, na_sentinel=-1):
Returns
-------
indices : array of ints
Array of insertion points with the same shape as `v`.
Array of insertion points with the same shape as `value`.

See Also
--------
Expand Down Expand Up @@ -1149,11 +1149,12 @@ def factorize(self, sort=False, na_sentinel=-1):
array([3, 4]) # eggs before milk
""")

@Substitution(klass='IndexOpsMixin', value='key')
@Substitution(klass='IndexOpsMixin')
@Appender(_shared_docs['searchsorted'])
def searchsorted(self, key, side='left', sorter=None):
@deprecate_kwarg(old_arg_name='key', new_arg_name='value')
def searchsorted(self, value, side='left', sorter=None):
# needs coercion on the key (DatetimeIndex does already)
return self.values.searchsorted(key, side=side, sorter=sorter)
return self.values.searchsorted(value, side=side, sorter=sorter)

_shared_docs['drop_duplicates'] = (
"""Return %(klass)s with duplicate values removed
Expand Down
7 changes: 4 additions & 3 deletions pandas/core/categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -1076,17 +1076,18 @@ def memory_usage(self, deep=False):
"""
return self._codes.nbytes + self._categories.memory_usage(deep=deep)

@Substitution(klass='Categorical', value='v')
@Substitution(klass='Categorical')
@Appender(_shared_docs['searchsorted'])
def searchsorted(self, v, side='left', sorter=None):
@deprecate_kwarg(old_arg_name='v', new_arg_name='value')
def searchsorted(self, value, side='left', sorter=None):
if not self.ordered:
raise ValueError("Categorical not ordered\nyou can use "
".as_ordered() to change the Categorical to an "
"ordered one")

from pandas.core.series import Series
values_as_codes = self.categories.values.searchsorted(
Series(v).values, side=side)
Series(value).values, side=side)

return self.codes.searchsorted(values_as_codes, sorter=sorter)

Expand Down
16 changes: 9 additions & 7 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -832,18 +832,19 @@ def _set_values(self, key, value):
self._data = self._data.setitem(indexer=key, value=value)
self._maybe_update_cacher()

def repeat(self, reps, *args, **kwargs):
@deprecate_kwarg(old_arg_name='reps', new_arg_name='repeats')
def repeat(self, repeats, *args, **kwargs):
"""
Repeat elements of an Series. Refer to `numpy.ndarray.repeat`
for more information about the `reps` argument.
for more information about the `repeats` argument.

See also
--------
numpy.ndarray.repeat
"""
nv.validate_repeat(args, kwargs)
new_index = self.index.repeat(reps)
new_values = self._values.repeat(reps)
new_index = self.index.repeat(repeats)
new_values = self._values.repeat(repeats)
return self._constructor(new_values,
index=new_index).__finalize__(self)

Expand Down Expand Up @@ -1509,12 +1510,13 @@ def dot(self, other):
else: # pragma: no cover
raise TypeError('unsupported type: %s' % type(other))

@Substitution(klass='Series', value='v')
@Substitution(klass='Series')
@Appender(base._shared_docs['searchsorted'])
def searchsorted(self, v, side='left', sorter=None):
@deprecate_kwarg(old_arg_name='v', new_arg_name='value')
def searchsorted(self, value, side='left', sorter=None):
if sorter is not None:
sorter = _ensure_platform_int(sorter)
return self._values.searchsorted(Series(v)._values,
return self._values.searchsorted(Series(value)._values,
side=side, sorter=sorter)

# -------------------------------------------------------------------
Expand Down
7 changes: 4 additions & 3 deletions pandas/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,17 +535,18 @@ def tolist(self):
"""
return list(self.values)

def repeat(self, n, *args, **kwargs):
@deprecate_kwarg(old_arg_name='n', new_arg_name='repeats')
def repeat(self, repeats, *args, **kwargs):
"""
Repeat elements of an Index. Refer to `numpy.ndarray.repeat`
for more information about the `n` argument.
for more information about the `repeats` argument.

See also
--------
numpy.ndarray.repeat
"""
nv.validate_repeat(args, kwargs)
return self._shallow_copy(self._values.repeat(n))
return self._shallow_copy(self._values.repeat(repeats))

def where(self, cond, other=None):
"""
Expand Down
5 changes: 3 additions & 2 deletions pandas/indexes/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -1166,10 +1166,11 @@ def append(self, other):
def argsort(self, *args, **kwargs):
return self.values.argsort(*args, **kwargs)

def repeat(self, n, *args, **kwargs):
@deprecate_kwarg(old_arg_name='n', new_arg_name='repeats')
def repeat(self, repeats, *args, **kwargs):
nv.validate_repeat(args, kwargs)
return MultiIndex(levels=self.levels,
labels=[label.view(np.ndarray).repeat(n)
labels=[label.view(np.ndarray).repeat(repeats)
for label in self.labels], names=self.names,
sortorder=self.sortorder, verify_integrity=False)

Expand Down
19 changes: 15 additions & 4 deletions pandas/tests/indexes/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
Float64Index, Int64Index,
CategoricalIndex, DatetimeIndex, TimedeltaIndex,
PeriodIndex)
from pandas.core.index import _get_combined_index
from pandas.util.testing import assert_almost_equal
from pandas.compat.numpy import np_datetime64_compat

Expand Down Expand Up @@ -1976,8 +1977,18 @@ def test_dropna(self):
with tm.assertRaisesRegexp(ValueError, msg):
pd.Index([1, 2, 3]).dropna(how='xxx')

def test_get_combined_index(self):
result = _get_combined_index([])
tm.assert_index_equal(result, Index([]))

def test_get_combined_index():
from pandas.core.index import _get_combined_index
result = _get_combined_index([])
tm.assert_index_equal(result, Index([]))
def test_repeat(self):
repeats = 2
idx = pd.Index([1, 2, 3])
expected = pd.Index([1, 1, 2, 2, 3, 3])

result = idx.repeat(repeats)
tm.assert_index_equal(result, expected)

with tm.assert_produces_warning(FutureWarning):
result = idx.repeat(n=repeats)
tm.assert_index_equal(result, expected)
4 changes: 4 additions & 0 deletions pandas/tests/indexes/test_multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ def test_repeat(self):
numbers, names.repeat(reps)], names=names)
tm.assert_index_equal(m.repeat(reps), expected)

with tm.assert_produces_warning(FutureWarning):
result = m.repeat(n=reps)
tm.assert_index_equal(result, expected)

def test_numpy_repeat(self):
reps = 2
numbers = [1, 2, 3]
Expand Down
17 changes: 17 additions & 0 deletions pandas/tests/series/test_analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1363,6 +1363,10 @@ def test_repeat(self):
exp = Series(s.values.repeat(5), index=s.index.values.repeat(5))
assert_series_equal(reps, exp)

with tm.assert_produces_warning(FutureWarning):
result = s.repeat(reps=5)
assert_series_equal(result, exp)

to_rep = [2, 3, 4]
reps = s.repeat(to_rep)
exp = Series(s.values.repeat(to_rep),
Expand All @@ -1378,6 +1382,19 @@ def test_numpy_repeat(self):
msg = "the 'axis' parameter is not supported"
tm.assertRaisesRegexp(ValueError, msg, np.repeat, s, 2, axis=0)

def test_searchsorted(self):
s = Series([1, 2, 3])

idx = s.searchsorted(1, side='left')
tm.assert_numpy_array_equal(idx, np.array([0], dtype=np.intp))

idx = s.searchsorted(1, side='right')
tm.assert_numpy_array_equal(idx, np.array([1], dtype=np.intp))

with tm.assert_produces_warning(FutureWarning):
idx = s.searchsorted(v=1, side='left')
tm.assert_numpy_array_equal(idx, np.array([0], dtype=np.intp))

def test_searchsorted_numeric_dtypes_scalar(self):
s = Series([1, 2, 90, 1000, 3e9])
r = s.searchsorted(30)
Expand Down
5 changes: 5 additions & 0 deletions pandas/tests/test_categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -1593,6 +1593,11 @@ def test_searchsorted(self):
self.assert_numpy_array_equal(res, exp)
self.assert_numpy_array_equal(res, chk)

with tm.assert_produces_warning(FutureWarning):
res = c1.searchsorted(v=['bread'])
exp = np.array([1], dtype=np.intp)
tm.assert_numpy_array_equal(res, exp)

def test_deprecated_labels(self):
# TODO: labels is deprecated and should be removed in 0.18 or 2017,
# whatever is earlier
Expand Down
13 changes: 7 additions & 6 deletions pandas/tseries/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -1620,15 +1620,16 @@ def normalize(self):
return DatetimeIndex(new_values, freq='infer', name=self.name,
tz=self.tz)

@Substitution(klass='DatetimeIndex', value='key')
@Substitution(klass='DatetimeIndex')
@Appender(_shared_docs['searchsorted'])
def searchsorted(self, key, side='left', sorter=None):
if isinstance(key, (np.ndarray, Index)):
key = np.array(key, dtype=_NS_DTYPE, copy=False)
@deprecate_kwarg(old_arg_name='key', new_arg_name='value')
def searchsorted(self, value, side='left', sorter=None):
if isinstance(value, (np.ndarray, Index)):
value = np.array(value, dtype=_NS_DTYPE, copy=False)
else:
key = _to_m8(key, tz=self.tz)
value = _to_m8(value, tz=self.tz)

return self.values.searchsorted(key, side=side)
return self.values.searchsorted(value, side=side)

def is_type_compatible(self, typ):
return typ == self.inferred_type or typ == 'datetime'
Expand Down
22 changes: 12 additions & 10 deletions pandas/tseries/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
from pandas.indexes.base import _index_shared_docs, _ensure_index

from pandas import compat
from pandas.util.decorators import Appender, cache_readonly, Substitution
from pandas.util.decorators import (Appender, Substitution, cache_readonly,
deprecate_kwarg)
from pandas.lib import infer_dtype
import pandas.tslib as tslib
from pandas.compat import zip, u
Expand Down Expand Up @@ -460,18 +461,19 @@ def astype(self, dtype, copy=True, how='start'):
return self.asfreq(freq=dtype.freq)
raise ValueError('Cannot cast PeriodIndex to dtype %s' % dtype)

@Substitution(klass='PeriodIndex', value='key')
@Substitution(klass='PeriodIndex')
@Appender(_shared_docs['searchsorted'])
def searchsorted(self, key, side='left', sorter=None):
if isinstance(key, Period):
if key.freq != self.freq:
msg = _DIFFERENT_FREQ_INDEX.format(self.freqstr, key.freqstr)
@deprecate_kwarg(old_arg_name='key', new_arg_name='value')
def searchsorted(self, value, side='left', sorter=None):
if isinstance(value, Period):
if value.freq != self.freq:
msg = _DIFFERENT_FREQ_INDEX.format(self.freqstr, value.freqstr)
raise IncompatibleFrequency(msg)
key = key.ordinal
elif isinstance(key, compat.string_types):
key = Period(key, freq=self.freq).ordinal
value = value.ordinal
elif isinstance(value, compat.string_types):
value = Period(value, freq=self.freq).ordinal

return self._values.searchsorted(key, side=side, sorter=sorter)
return self._values.searchsorted(value, side=side, sorter=sorter)

@property
def is_all_dates(self):
Expand Down
15 changes: 8 additions & 7 deletions pandas/tseries/tdi.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from pandas.indexes.base import _index_shared_docs
import pandas.core.common as com
import pandas.types.concat as _concat
from pandas.util.decorators import Appender, Substitution
from pandas.util.decorators import Appender, Substitution, deprecate_kwarg
from pandas.tseries.base import TimelikeOps, DatetimeIndexOpsMixin
from pandas.tseries.timedeltas import (to_timedelta,
_coerce_scalar_to_timedelta_type)
Expand Down Expand Up @@ -785,15 +785,16 @@ def _partial_td_slice(self, key, freq, use_lhs=True, use_rhs=True):
# # try to find a the dates
# return (lhs_mask & rhs_mask).nonzero()[0]

@Substitution(klass='TimedeltaIndex', value='key')
@Substitution(klass='TimedeltaIndex')
@Appender(_shared_docs['searchsorted'])
def searchsorted(self, key, side='left', sorter=None):
if isinstance(key, (np.ndarray, Index)):
key = np.array(key, dtype=_TD_DTYPE, copy=False)
@deprecate_kwarg(old_arg_name='key', new_arg_name='value')
def searchsorted(self, value, side='left', sorter=None):
if isinstance(value, (np.ndarray, Index)):
value = np.array(value, dtype=_TD_DTYPE, copy=False)
else:
key = _to_m8(key)
value = _to_m8(value)

return self.values.searchsorted(key, side=side, sorter=sorter)
return self.values.searchsorted(value, side=side, sorter=sorter)

def is_type_compatible(self, typ):
return typ == self.inferred_type or typ == 'timedelta'
Expand Down
3 changes: 3 additions & 0 deletions pandas/tseries/tests/test_period.py
Original file line number Diff line number Diff line change
Expand Up @@ -3698,6 +3698,9 @@ def test_searchsorted(self):
with self.assertRaisesRegexp(period.IncompatibleFrequency, msg):
pidx.searchsorted(pd.Period('2014-01-01', freq='5D'))

with tm.assert_produces_warning(FutureWarning):
pidx.searchsorted(key=p2)

def test_round_trip(self):

p = Period('2000Q1')
Expand Down