diff --git a/doc/source/indexing.rst b/doc/source/indexing.rst index 1ea6662a4edb0..9dd8b2d391782 100644 --- a/doc/source/indexing.rst +++ b/doc/source/indexing.rst @@ -1586,6 +1586,25 @@ If you create an index yourself, you can just assign it to the ``index`` field: data.index = index +.. versionadded:: 0.20.0 + +A new index can also be created on an existing object by passing values +to the ``rename`` method. + +.. ipython:: python + :suppress: + + data = data.reset_index() + +.. ipython:: python + + data + data.rename(index=['a', 'b', 'c', 'd']) + data.rename(columns=['q', 'w', 'r', 't']) + + + + .. _indexing.view_versus_copy: Returning a view versus a copy diff --git a/doc/source/whatsnew/v0.20.0.txt b/doc/source/whatsnew/v0.20.0.txt index a947b4f3ca0ac..f0e2680ca8eeb 100644 --- a/doc/source/whatsnew/v0.20.0.txt +++ b/doc/source/whatsnew/v0.20.0.txt @@ -113,7 +113,7 @@ Other enhancements - ``pandas.io.json.json_normalize()`` gained the option ``errors='ignore'|'raise'``; the default is ``errors='raise'`` which is backward compatible. (:issue:`14583`) - ``.select_dtypes()`` now allows the string 'datetimetz' to generically select datetimes with tz (:issue:`14910`) - +- ``pd.DataFrame.rename`` now accepts a list-like for the ``index`` and ``columns`` parameters to assign new axis values (:issue:`14829`) .. _whatsnew_0200.api_breaking: diff --git a/pandas/core/frame.py b/pandas/core/frame.py index d96fb094f5d5c..f3f621fdd4029 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2842,6 +2842,11 @@ def set_index(self, keys, drop=True, append=False, inplace=False, Returns ------- dataframe : DataFrame + + See Also + -------- + DataFrame.rename + """ if not isinstance(keys, list): keys = [keys] diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 8ce4c4b00454b..98be360ea1762 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -581,7 +581,7 @@ def swaplevel(self, i=-2, j=-1, axis=0): ---------- %(axes)s : scalar, list-like, dict-like or function, optional Scalar or list-like will alter the ``Series.name`` attribute, - and raise on DataFrame or Panel. + for DataFrame list-like will form new values for the axes, dict-like or functions are transformations to apply to that axis' values copy : boolean, default True @@ -635,6 +635,11 @@ def swaplevel(self, i=-2, j=-1, axis=0): 0 1 4 1 2 5 2 3 6 + >>> df.rename(index=['a', 'b', 'c'], columns=[1, 2]) + 1 2 + a 1 4 + b 2 5 + c 3 6 """ @Appender(_shared_docs['rename'] % dict(axes='axes keywords for this' @@ -672,13 +677,17 @@ def f(x): # start in the axis order to eliminate too many copies for axis in lrange(self._AXIS_LEN): v = axes.get(self._AXIS_NAMES[axis]) + baxis = self._get_block_manager_axis(axis) if v is None: continue - f = _get_rename_function(v) - baxis = self._get_block_manager_axis(axis) - result._data = result._data.rename_axis(f, axis=baxis, copy=copy) - result._clear_item_cache() + f = _get_rename_function(v) + if is_list_like(f) and not callable(f): + result._set_axis(axis=baxis, labels=v) + else: + result._data = result._data.rename_axis(f, axis=baxis, + copy=copy) + result._clear_item_cache() if inplace: self._update_inplace(result._data) diff --git a/pandas/tests/test_generic.py b/pandas/tests/test_generic.py index 3500ce913462a..be6092ca3a5e7 100644 --- a/pandas/tests/test_generic.py +++ b/pandas/tests/test_generic.py @@ -1504,6 +1504,30 @@ def test_to_xarray(self): expected, check_index_type=False) + def test_rename_list_like(self): + # GH 14829 + df = pd.DataFrame({'a': [1, 2], 'b': [3, 4]}, columns=['a', 'b']) + + expected = df.copy() + expected.columns = ['J', 'K'] + result = df.rename(columns=['J', 'K']) + assert_frame_equal(result, expected) + + expected.index = ['a', 'b'] + for box in [list, np.array, Index]: + result = df.rename(columns=box(['J', 'K']), index=box(['a', 'b'])) + assert_frame_equal(result, expected) + + result = df.copy() + result.rename(columns=['J', 'K'], index=['a', 'b'], inplace=True) + assert_frame_equal(result, expected) + + with tm.assertRaises(ValueError): + df.rename(index=[1, 3, 3]) + + with tm.assertRaises(TypeError): + df.rename(index=1) + class TestPanel(tm.TestCase, Generic): _typ = Panel