Repository: pandas-dev/pandas

Issue:
rename_axis inplace=True
#### Code Sample, a copy-pastable example if possible

```python
import pandas as pd
import numpy as np

df = pd.DataFrame({'a':np.random.random(10),'b':np.random.random(10)})
df
df.rename_axis('numbers', inplace=True)
df
```
#### Problem description

df.rename_axis with the inplace=True should return None and make the named axis change the index name in the original object.  However, up listing df again, no index name is present.

#### Expected Output
df.index.name should return 'numbers'
#### Output of ``pd.show_versions()``


<details>
INSTALLED VERSIONS
------------------
commit: None
python: 3.5.2.final.0
python-bits: 64
OS: Linux
OS-release: 4.4.0-66-generic
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8

pandas: 0.18.1
nose: 1.3.7
pip: 9.0.1
setuptools: 27.2.0
Cython: 0.24.1
numpy: 1.11.1
scipy: 0.18.1
statsmodels: 0.6.1
xarray: None
IPython: 5.1.0
sphinx: 1.4.6
patsy: 0.4.1
dateutil: 2.5.3
pytz: 2016.6.1
blosc: None
bottleneck: 1.1.0
tables: 3.2.3.1
numexpr: 2.6.1
matplotlib: 1.5.3
openpyxl: 2.3.2
xlrd: 1.0.0
xlwt: 1.1.2
xlsxwriter: 0.9.3
lxml: 3.6.4
bs4: 4.5.1
html5lib: 0.999999999
httplib2: None
apiclient: None
sqlalchemy: 1.0.13
pymysql: None
psycopg2: None
jinja2: 2.8
boto: 2.42.0
pandas_datareader: 0.3.0.post

</details>



Discussion:
Not supporting inplace was a deliberate decision in https://github.com/pandas-dev/pandas/pull/11980
If you want to change it inplace use `df.index.name = name`.

We could raise an exception if your renaming the axis label and `inplace` is true, rather than silently ignoring. Mind submitting a PR to fix that?
could support ``inplace`` as well, not a big deal (and we are already way down that road :<)

Resolving patch:
diff --git a/pandas/core/generic.py b/pandas/core/generic.py
--- a/pandas/core/generic.py
+++ b/pandas/core/generic.py
@@ -753,7 +753,7 @@ def rename_axis(self, mapper, axis=0, copy=True, inplace=False):
 
         Returns
         -------
-        renamed : type of caller
+        renamed : type of caller or None if inplace=True
 
         See Also
         --------
@@ -784,16 +784,16 @@ def rename_axis(self, mapper, axis=0, copy=True, inplace=False):
         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)
+            return self._set_axis_name(mapper, axis=axis, inplace=inplace)
         else:
             axis = self._get_axis_name(axis)
             d = {'copy': copy, 'inplace': inplace}
             d[axis] = mapper
             return self.rename(**d)
 
-    def _set_axis_name(self, name, axis=0):
+    def _set_axis_name(self, name, axis=0, inplace=False):
         """
-        Alter the name or names of the axis, returning self.
+        Alter the name or names of the axis.
 
         Parameters
         ----------
@@ -801,10 +801,14 @@ def _set_axis_name(self, name, axis=0):
             Name for the Index, or list of names for the MultiIndex
         axis : int or str
            0 or 'index' for the index; 1 or 'columns' for the columns
+        inplace : bool
+            whether to modify `self` directly or return a copy
+
+            .. versionadded: 0.21.0
 
         Returns
         -------
-        renamed : type of caller
+        renamed : type of caller or None if inplace=True
 
         See Also
         --------
@@ -831,9 +835,11 @@ def _set_axis_name(self, name, axis=0):
         axis = self._get_axis_number(axis)
         idx = self._get_axis(axis).set_names(name)
 
-        renamed = self.copy(deep=True)
+        inplace = validate_bool_kwarg(inplace, 'inplace')
+        renamed = self if inplace else self.copy()
         renamed.set_axis(axis, idx)
-        return renamed
+        if not inplace:
+            return renamed
 
     # ----------------------------------------------------------------------
     # Comparisons


Test patch:
diff --git a/pandas/tests/frame/test_alter_axes.py b/pandas/tests/frame/test_alter_axes.py
--- a/pandas/tests/frame/test_alter_axes.py
+++ b/pandas/tests/frame/test_alter_axes.py
@@ -418,6 +418,23 @@ def test_rename(self):
                               pd.Index(['bar', 'foo'], name='name'))
         assert renamed.index.name == renamer.index.name
 
+    def test_rename_axis_inplace(self):
+        # GH 15704
+        frame = self.frame.copy()
+        expected = frame.rename_axis('foo')
+        result = frame.copy()
+        no_return = result.rename_axis('foo', inplace=True)
+
+        assert no_return is None
+        assert_frame_equal(result, expected)
+
+        expected = frame.rename_axis('bar', axis=1)
+        result = frame.copy()
+        no_return = result.rename_axis('bar', axis=1, inplace=True)
+
+        assert no_return is None
+        assert_frame_equal(result, expected)
+
     def test_rename_multiindex(self):
 
         tuples_index = [('foo1', 'bar1'), ('foo2', 'bar2')]
diff --git a/pandas/tests/series/test_alter_axes.py b/pandas/tests/series/test_alter_axes.py
--- a/pandas/tests/series/test_alter_axes.py
+++ b/pandas/tests/series/test_alter_axes.py
@@ -224,3 +224,13 @@ def test_reorder_levels(self):
 
         result = s.reorder_levels(['L0', 'L0', 'L0'])
         assert_series_equal(result, expected)
+
+    def test_rename_axis_inplace(self):
+        # GH 15704
+        series = self.ts.copy()
+        expected = series.rename_axis('foo')
+        result = series.copy()
+        no_return = result.rename_axis('foo', inplace=True)
+
+        assert no_return is None
+        assert_series_equal(result, expected)