Code Sample, a copy-pastable example if possible
In [2]: mi = pd.MultiIndex.from_tuples([(1,2), (3,4)])
In [3]: pd.DataFrame([[1], [2]], index=mi).rename('c', level=1)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-4199859c8380> in <module>()
----> 1 pd.DataFrame([[1], [2]], index=mi).rename('c', level=1)
/home/pietro/nobackup/repo/pandas/pandas/core/frame.py in rename(self, index, columns, **kwargs)
2845 def rename(self, index=None, columns=None, **kwargs):
2846 return super(DataFrame, self).rename(index=index, columns=columns,
-> 2847 **kwargs)
2848
2849 @Appender(_shared_docs['fillna'] % _shared_doc_kwargs)
/home/pietro/nobackup/repo/pandas/pandas/core/generic.py in rename(self, *args, **kwargs)
845 level = self.axes[axis]._get_level_number(level)
846 result._data = result._data.rename_axis(f, axis=baxis, copy=copy,
--> 847 level=level)
848 result._clear_item_cache()
849
/home/pietro/nobackup/repo/pandas/pandas/core/internals.py in rename_axis(self, mapper, axis, copy, level)
2956 """
2957 obj = self.copy(deep=copy)
-> 2958 obj.set_axis(axis, _transform_index(self.axes[axis], mapper, level))
2959 return obj
2960
/home/pietro/nobackup/repo/pandas/pandas/core/internals.py in _transform_index(index, func, level)
4842 if level is not None:
4843 items = [tuple(func(y) if i == level else y
-> 4844 for i, y in enumerate(x)) for x in index]
4845 else:
4846 items = [tuple(func(y) for y in x) for x in index]
/home/pietro/nobackup/repo/pandas/pandas/core/internals.py in <listcomp>(.0)
4842 if level is not None:
4843 items = [tuple(func(y) if i == level else y
-> 4844 for i, y in enumerate(x)) for x in index]
4845 else:
4846 items = [tuple(func(y) for y in x) for x in index]
/home/pietro/nobackup/repo/pandas/pandas/core/internals.py in <genexpr>(.0)
4842 if level is not None:
4843 items = [tuple(func(y) if i == level else y
-> 4844 for i, y in enumerate(x)) for x in index]
4845 else:
4846 items = [tuple(func(y) for y in x) for x in index]
TypeError: 'str' object is not callable
Problem description
Apparently, the level
argument works only for relabeling, not for renaming the level. This is not, however, mentioned in the docs.
This is closely related to #14829 (that is: whatever will the new method for index renaming be called, it will need not just to steal the related logics from .rename
, but also to implement this one, which is currently absent).
Expected Output
Same as
In [4]: df = pd.DataFrame([[1], [2]], index=mi)
In [5]: df.index.names = ['a', 'c']
In [6]: df
Out[6]:
0
a c
1 2 1
3 4 2
Output of pd.show_versions()
Comment From: gfyoung
@toobaz : I'm a little confused by what you're doing here. According to the docs, you should not be passing in a scalar for the index
parameter when using a DataFrame
:
Scalar or list-like will alter the Series.name attribute, and raise on DataFrame or Panel
Comment From: toobaz
Sorry, you are right. I got confused. I expected rename
to allow me to rename the index, but it just doesn't do this, regardless of the index being flat or not.