Skip to content

Commit

Permalink
API: Deprecate renamae_axis and reindex_axis
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAugspurger committed Oct 10, 2017
1 parent 727ea20 commit 8c54f26
Show file tree
Hide file tree
Showing 20 changed files with 97 additions and 48 deletions.
7 changes: 5 additions & 2 deletions doc/source/basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1201,8 +1201,11 @@ With a DataFrame, you can simultaneously reindex the index and columns:
df
df.reindex(index=['c', 'f', 'b'], columns=['three', 'two', 'one'])
For convenience, you may utilize the :meth:`~Series.reindex_axis` method, which
takes the labels and a keyword ``axis`` parameter.
You may also use ``reindex`` with an ``axis`` keyword:

.. ipython:: python
df.reindex(index=['c', 'f', 'b'], axis='index')
Note that the ``Index`` objects containing the actual axis labels can be
**shared** between objects. So if we have a Series and a DataFrame, the
Expand Down
2 changes: 2 additions & 0 deletions doc/source/whatsnew/v0.21.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,8 @@ Deprecations
- ``.get_value`` and ``.set_value`` on ``Series``, ``DataFrame``, ``Panel``, ``SparseSeries``, and ``SparseDataFrame`` are deprecated in favor of using ``.iat[]`` or ``.at[]`` accessors (:issue:`15269`)
- Passing a non-existent column in ``.to_excel(..., columns=)`` is deprecated and will raise a ``KeyError`` in the future (:issue:`17295`)
- ``raise_on_error`` parameter to :func:`Series.where`, :func:`Series.mask`, :func:`DataFrame.where`, :func:`DataFrame.mask` is deprecated, in favor of ``errors=`` (:issue:`14968`)
- Using :meth:`DataFrame.rename_axis` and :meth:`Series.rename_axis` to alter index or column *labels* is now deprecated in favor of using ``.rename``. ``rename_axis`` may still be used to alter the name of the index or columns (:issue:`17833`).
- :meth:`~NDFrame.reindex_axis` has been deprecated in favor of :meth:`~NDFrame.reindex`. See :ref`here` <whatsnew_0210.enhancements.rename_reindex_axis> for more (:issue:`17833`).

.. _whatsnew_0210.deprecations.select:

Expand Down
7 changes: 2 additions & 5 deletions pandas/core/computation/align.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def _align_core(terms):
for axis, items in zip(range(ndim), axes):
ti = terms[i].value

# TODO: handle this for when reindex_axis is removed...
if hasattr(ti, 'reindex_axis'):
transpose = isinstance(ti, pd.Series) and naxes > 1
reindexer = axes[naxes - 1] if transpose else items
Expand All @@ -104,11 +105,7 @@ def _align_core(terms):
).format(axis=axis, term=terms[i].name, ordm=ordm)
warnings.warn(w, category=PerformanceWarning, stacklevel=6)

if transpose:
f = partial(ti.reindex, index=reindexer, copy=False)
else:
f = partial(ti.reindex_axis, reindexer, axis=axis,
copy=False)
f = partial(ti.reindex, reindexer, axis=axis, copy=False)

terms[i].update(f())

Expand Down
2 changes: 1 addition & 1 deletion pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -2736,7 +2736,7 @@ def reindexer(value):
if isinstance(loc, (slice, Series, np.ndarray, Index)):
cols = maybe_droplevels(self.columns[loc], key)
if len(cols) and not cols.equals(value.columns):
value = value.reindex_axis(cols, axis=1)
value = value.reindex(cols, axis=1)
# now align rows
value = reindexer(value).T

Expand Down
44 changes: 27 additions & 17 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def __init__(self, data, axes=None, copy=False, dtype=None,

if axes is not None:
for i, ax in enumerate(axes):
data = data.reindex_axis(ax, axis=i)
data = data.reindex(ax, axis=i)

object.__setattr__(self, 'is_copy', None)
object.__setattr__(self, '_data', data)
Expand Down Expand Up @@ -893,17 +893,12 @@ def f(x):
rename.__doc__ = _shared_docs['rename']

def rename_axis(self, mapper, axis=0, copy=True, inplace=False):
"""
Alter index and / or columns using input function or functions.
A scalar or list-like for ``mapper`` will alter the ``Index.name``
or ``MultiIndex.names`` attribute.
A function or dict for ``mapper`` will alter the labels.
Function / dict values must be unique (1-to-1). Labels not contained in
a dict / Series will be left as-is.
"""Alter the name of the index or columns.
Parameters
----------
mapper : scalar, list-like, dict-like or function, optional
mapper : scalar, list-like, optional
Value to set the axis name attribute.
axis : int or string, default 0
copy : boolean, default True
Also copy underlying data
Expand All @@ -913,6 +908,13 @@ def rename_axis(self, mapper, axis=0, copy=True, inplace=False):
-------
renamed : type of caller or None if inplace=True
Notes
-----
Prior to version 0.21.0, ``rename_axis`` could also be used to change
the axis *labels* by passing a mapping or scalar. This behavior is
deprecated and will be removed in a future version. Use ``rename``
instead.
See Also
--------
pandas.NDFrame.rename
Expand All @@ -922,29 +924,29 @@ def rename_axis(self, mapper, axis=0, copy=True, inplace=False):
--------
>>> df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
>>> df.rename_axis("foo") # scalar, alters df.index.name
>>> df.rename_axis("foo")
A B
foo
0 1 4
1 2 5
2 3 6
>>> df.rename_axis(lambda x: 2 * x) # function: alters labels
A B
0 1 4
2 2 5
4 3 6
>>> df.rename_axis({"A": "ehh", "C": "see"}, axis="columns") # mapping
ehh B
>>> df.rename_axis("bar", axis="columns")
bar A B
0 1 4
1 2 5
2 3 6
"""
inplace = validate_bool_kwarg(inplace, 'inplace')
non_mapper = is_scalar(mapper) or (is_list_like(mapper) and not
is_dict_like(mapper))
if non_mapper:
return self._set_axis_name(mapper, axis=axis, inplace=inplace)
else:
msg = ("Using 'rename_axis' to alter labels is deprecated. "
"Use '.rename' instead")
warnings.warn(msg, FutureWarning, stacklevel=2)
axis = self._get_axis_name(axis)
d = {'copy': copy, 'inplace': inplace}
d[axis] = mapper
Expand Down Expand Up @@ -2981,6 +2983,11 @@ def reindex(self, *args, **kwargs):
tolerance = kwargs.pop('tolerance', None)
fill_value = kwargs.pop('fill_value', np.nan)

# Series.reindex doesn't use / need the axis kwarg
# We pop and ignore it here, to make writing Series/Frame generic code
# easier
kwargs.pop("axis", None)

if kwargs:
raise TypeError('reindex() got an unexpected keyword '
'argument "{0}"'.format(list(kwargs.keys())[0]))
Expand Down Expand Up @@ -3085,11 +3092,14 @@ def _reindex_multi(self, axes, copy, fill_value):
@Appender(_shared_docs['reindex_axis'] % _shared_doc_kwargs)
def reindex_axis(self, labels, axis=0, method=None, level=None, copy=True,
limit=None, fill_value=np.nan):
msg = ("'.reindex_axis' is deprecated and will be removed in a future "
"version. Use '.reindex' instead.")
self._consolidate_inplace()

axis_name = self._get_axis_name(axis)
axis_values = self._get_axis(axis_name)
method = missing.clean_reindex_fill_method(method)
warnings.warn(msg, FutureWarning, stacklevel=3)
new_index, indexer = axis_values.reindex(labels, method, level,
limit=limit)
return self._reindex_with_indexers({axis: [new_index, indexer]},
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/groupby.py
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@ def reset_identity(values):
result.index.get_indexer_for(ax.values))
result = result.take(indexer, axis=self.axis)
else:
result = result.reindex_axis(ax, axis=self.axis)
result = result.reindex(ax, axis=self.axis)

elif self.group_keys:

Expand Down Expand Up @@ -4580,7 +4580,7 @@ def _get_sorted_data(self):

# this is sort of wasteful but...
sorted_axis = data.axes[self.axis].take(self.sort_idx)
sorted_data = data.reindex_axis(sorted_axis, axis=self.axis)
sorted_data = data.reindex(sorted_axis, axis=self.axis)

return sorted_data

Expand Down
4 changes: 2 additions & 2 deletions pandas/core/indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ def _setitem_with_indexer(self, indexer, value):
# so the object is the same
index = self.obj._get_axis(i)
labels = index.insert(len(index), key)
self.obj._data = self.obj.reindex_axis(labels, i)._data
self.obj._data = self.obj.reindex(labels, axis=i)._data
self.obj._maybe_update_cacher(clear=True)
self.obj.is_copy = None

Expand Down Expand Up @@ -1132,7 +1132,7 @@ def _getitem_iterable(self, key, axis=None):
if labels.is_unique and Index(keyarr).is_unique:

try:
return self.obj.reindex_axis(keyarr, axis=axis)
return self.obj.reindex(keyarr, axis=axis)
except AttributeError:

# Series
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/internals.py
Original file line number Diff line number Diff line change
Expand Up @@ -3283,8 +3283,8 @@ def apply(self, f, axes=None, filter=None, do_integrity_check=False,

for k, obj in aligned_args.items():
axis = getattr(obj, '_info_axis_number', 0)
kwargs[k] = obj.reindex_axis(b_items, axis=axis,
copy=align_copy)
kwargs[k] = obj.reindex(b_items, axis=axis,
copy=align_copy)

kwargs['mgr'] = self
applied = getattr(b, f)(**kwargs)
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,7 @@ def dropna(self, axis=0, how='any', inplace=False):
cond = mask == per_slice

new_ax = self._get_axis(axis)[cond]
result = self.reindex_axis(new_ax, axis=axis)
result = self.reindex(new_ax, axis=axis)
if inplace:
self._update_inplace(result)
else:
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/reshape/pivot.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,14 @@ def pivot_table(data, values=None, index=None, columns=None, aggfunc='mean',
try:
m = MultiIndex.from_arrays(cartesian_product(table.index.levels),
names=table.index.names)
table = table.reindex_axis(m, axis=0)
table = table.reindex(m, axis=0)
except AttributeError:
pass # it's a single level

try:
m = MultiIndex.from_arrays(cartesian_product(table.columns.levels),
names=table.columns.names)
table = table.reindex_axis(m, axis=1)
table = table.reindex(m, axis=1)
except AttributeError:
pass # it's a single level or a series

Expand Down
4 changes: 4 additions & 0 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -2615,6 +2615,10 @@ def reindex_axis(self, labels, axis=0, **kwargs):
""" for compatibility with higher dims """
if axis != 0:
raise ValueError("cannot reindex series on non-zero axis!")
msg = ("'.reindex_axis' is deprecated and will be removed in a future "
"version. Use '.reindex' instead.")
warnings.warn(msg, FutureWarning, stacklevel=2)

return self.reindex(index=labels, **kwargs)

def memory_usage(self, index=True, deep=False):
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/sparse/scipy_sparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,5 @@ def _coo_to_sparse_series(A, dense_index=False):
i = range(A.shape[0])
j = range(A.shape[1])
ind = MultiIndex.from_product([i, j])
s = s.reindex_axis(ind)
s = s.reindex(ind)
return s
2 changes: 1 addition & 1 deletion pandas/io/pytables.py
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,7 @@ def append_to_multiple(self, d, value, selector, data_columns=None,
dc = data_columns if k == selector else None

# compute the val
val = value.reindex_axis(v, axis=axis)
val = value.reindex(v, axis=axis)

self.append(k, val, data_columns=dc, **kwargs)

Expand Down
2 changes: 1 addition & 1 deletion pandas/plotting/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ def _parse_errorbars(self, label, err):
from pandas import DataFrame, Series

def match_labels(data, e):
e = e.reindex_axis(data.index)
e = e.reindex(data.index)
return e

# key-matched DataFrame
Expand Down
19 changes: 19 additions & 0 deletions pandas/tests/frame/test_alter_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,25 @@ def test_rename_axis_inplace(self):
assert no_return is None
assert_frame_equal(result, expected)

def test_rename_axis_warns(self):
# https://github.com/pandas-dev/pandas/issues/17833
df = pd.DataFrame({"A": [1, 2], "B": [1, 2]})
with tm.assert_produces_warning(FutureWarning) as w:
df.rename_axis(id, axis=0)
assert 'rename' in str(w[0].message)

with tm.assert_produces_warning(FutureWarning) as w:
df.rename_axis({0: 10, 1: 20}, axis=0)
assert 'rename' in str(w[0].message)

with tm.assert_produces_warning(FutureWarning) as w:
df.rename_axis(id, axis=1)
assert 'rename' in str(w[0].message)

with tm.assert_produces_warning(FutureWarning) as w:
df['A'].rename_axis(id)
assert 'rename' in str(w[0].message)

def test_rename_multiindex(self):

tuples_index = [('foo1', 'bar1'), ('foo2', 'bar2')]
Expand Down
18 changes: 13 additions & 5 deletions pandas/tests/frame/test_axis_select_reindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,11 +418,13 @@ def test_reindex_fill_value(self):
assert_frame_equal(result, expected)

# reindex_axis
result = df.reindex_axis(lrange(15), fill_value=0., axis=0)
with tm.assert_produces_warning(FutureWarning):
result = df.reindex_axis(lrange(15), fill_value=0., axis=0)
expected = df.reindex(lrange(15)).fillna(0)
assert_frame_equal(result, expected)

result = df.reindex_axis(lrange(5), fill_value=0., axis=1)
with tm.assert_produces_warning(FutureWarning):
result = df.reindex_axis(lrange(5), fill_value=0., axis=1)
expected = df.reindex(columns=lrange(5)).fillna(0)
assert_frame_equal(result, expected)

Expand Down Expand Up @@ -1030,20 +1032,26 @@ def test_reindex_corner(self):

def test_reindex_axis(self):
cols = ['A', 'B', 'E']
reindexed1 = self.intframe.reindex_axis(cols, axis=1)
with tm.assert_produces_warning(FutureWarning) as m:
reindexed1 = self.intframe.reindex_axis(cols, axis=1)
assert 'reindex' in str(m[0].message)
reindexed2 = self.intframe.reindex(columns=cols)
assert_frame_equal(reindexed1, reindexed2)

rows = self.intframe.index[0:5]
reindexed1 = self.intframe.reindex_axis(rows, axis=0)
with tm.assert_produces_warning(FutureWarning) as m:
reindexed1 = self.intframe.reindex_axis(rows, axis=0)
assert 'reindex' in str(m[0].message)
reindexed2 = self.intframe.reindex(index=rows)
assert_frame_equal(reindexed1, reindexed2)

pytest.raises(ValueError, self.intframe.reindex_axis, rows, axis=2)

# no-op case
cols = self.frame.columns.copy()
newFrame = self.frame.reindex_axis(cols, axis=1)
with tm.assert_produces_warning(FutureWarning) as m:
newFrame = self.frame.reindex_axis(cols, axis=1)
assert 'reindex' in str(m[0].message)
assert_frame_equal(newFrame, self.frame)

def test_reindex_with_nans(self):
Expand Down
6 changes: 3 additions & 3 deletions pandas/tests/reshape/test_reshape.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ def test_include_na(self):
'a': {0: 1, 1: 0, 2: 0},
'b': {0: 0, 1: 1, 2: 0}},
dtype=np.uint8)
exp_na = exp_na.reindex_axis(['a', 'b', nan], 1)
exp_na = exp_na.reindex(['a', 'b', nan], axis=1)
# hack (NaN handling in assert_index_equal)
exp_na.columns = res_na.columns
assert_frame_equal(res_na, exp_na)
Expand Down Expand Up @@ -542,8 +542,8 @@ def test_basic_drop_first_NA(self):
2: 0},
nan: {0: 0,
1: 0,
2: 1}}, dtype=np.uint8).reindex_axis(
['b', nan], 1)
2: 1}}, dtype=np.uint8).reindex(
['b', nan], axis=1)
assert_frame_equal(res_na, exp_na)

res_just_na = get_dummies([nan], dummy_na=True, sparse=self.sparse,
Expand Down
6 changes: 6 additions & 0 deletions pandas/tests/sparse/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -1414,6 +1414,12 @@ def test_deprecated_numpy_func_call(self):
check_stacklevel=False):
getattr(getattr(self, series), func)()

def test_deprecated_reindex_axis(self):
# https://github.com/pandas-dev/pandas/issues/17833
with tm.assert_produces_warning(FutureWarning) as m:
self.bseries.reindex_axis([0, 1, 2])
assert 'reindex' in str(m[0].message)


@pytest.mark.parametrize(
'datetime_type', (np.datetime64,
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/test_multilevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -1805,7 +1805,7 @@ def test_reindex_level_partial_selection(self):
expected = self.frame.iloc[[0, 1, 2, 7, 8, 9]]
tm.assert_frame_equal(result, expected)

result = self.frame.T.reindex_axis(['foo', 'qux'], axis=1, level=0)
result = self.frame.T.reindex(['foo', 'qux'], axis=1, level=0)
tm.assert_frame_equal(result, expected.T)

result = self.frame.loc[['foo', 'qux']]
Expand Down
Loading

0 comments on commit 8c54f26

Please sign in to comment.