Skip to content

Commit cb81978

Browse files
committed
ENH: implement Panel.rename_axis, GH #243
1 parent a663412 commit cb81978

File tree

6 files changed

+78
-27
lines changed

6 files changed

+78
-27
lines changed

RELEASE.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ feedback on the library.
119119
#253)
120120
- Can use & and | to intersection / union Index objects, respectively (GH
121121
#261)
122+
- Added `pivot_table` convenience function to pandas namespace (GH #234)
123+
- Implemented `Panel.rename_axis` function (GH #243)
122124

123125
**Improvements to existing features**
124126

pandas/core/common.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,3 +531,4 @@ def _asarray_tuplesafe(values, dtype=None):
531531
result[:] = values
532532

533533
return result
534+

pandas/core/frame.py

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,27 +1474,14 @@ def rename(self, index=None, columns=None, copy=True):
14741474
-------
14751475
renamed : DataFrame (new object)
14761476
"""
1477-
if isinstance(index, (dict, Series)):
1478-
def index_f(x):
1479-
if x in index:
1480-
return index[x]
1481-
else:
1482-
return x
1483-
else:
1484-
index_f = index
1485-
1486-
if isinstance(columns, (dict, Series)):
1487-
def columns_f(x):
1488-
if x in columns:
1489-
return columns[x]
1490-
else:
1491-
return x
1492-
else:
1493-
columns_f = columns
1477+
from pandas.core.series import _get_rename_function
14941478

14951479
if index is None and columns is None:
14961480
raise Exception('must pass either index or columns')
14971481

1482+
index_f = _get_rename_function(index)
1483+
columns_f = _get_rename_function(columns)
1484+
14981485
self._consolidate_inplace()
14991486

15001487
result = self.copy(deep=copy)

pandas/core/generic.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,3 +458,40 @@ def add_suffix(self, suffix):
458458
"""
459459
new_data = self._data.add_suffix(suffix)
460460
return self._constructor(new_data)
461+
462+
def rename_axis(self, mapper, axis=0, copy=True):
463+
"""
464+
Alter index and / or columns using input function or
465+
functions. Function / dict values must be unique (1-to-1). Labels not
466+
contained in a dict / Series will be left as-is.
467+
468+
Parameters
469+
----------
470+
index : dict-like or function, optional
471+
Transformation to apply to index values
472+
columns : dict-like or function, optional
473+
Transformation to apply to column values
474+
copy : boolean, default True
475+
Also copy underlying data
476+
477+
See also
478+
--------
479+
Series.rename
480+
481+
Returns
482+
-------
483+
renamed : DataFrame (new object)
484+
"""
485+
# should move this at some point
486+
from pandas.core.series import _get_rename_function
487+
488+
mapper_f = _get_rename_function(mapper)
489+
490+
if axis == 0:
491+
new_data = self._data.rename_items(mapper_f, copydata=copy)
492+
else:
493+
new_data = self._data.rename_axis(mapper_f, axis=axis)
494+
if copy:
495+
new_data = new_data.copy()
496+
497+
return self._constructor(new_data)

pandas/core/series.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1858,15 +1858,7 @@ def rename(self, mapper):
18581858
-------
18591859
renamed : Series (new object)
18601860
"""
1861-
if isinstance(mapper, (dict, Series)):
1862-
def mapper_f(x):
1863-
if x in mapper:
1864-
return mapper[x]
1865-
else:
1866-
return x
1867-
else:
1868-
mapper_f = mapper
1869-
1861+
mapper_f = _get_rename_function(mapper)
18701862
result = self.copy()
18711863
result.index = [mapper_f(x) for x in self.index]
18721864

@@ -1888,3 +1880,16 @@ def remove_na(arr):
18881880
Return array containing only true/non-NaN values, possibly empty.
18891881
"""
18901882
return arr[notnull(arr)]
1883+
1884+
1885+
def _get_rename_function(mapper):
1886+
if isinstance(mapper, (dict, Series)):
1887+
def f(x):
1888+
if x in mapper:
1889+
return mapper[x]
1890+
else:
1891+
return x
1892+
else:
1893+
f = mapper
1894+
1895+
return f

pandas/tests/test_panel.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,26 @@ def test_repr_empty(self):
830830
empty = Panel()
831831
repr(empty)
832832

833+
def test_rename(self):
834+
mapper = {
835+
'ItemA' : 'foo',
836+
'ItemB' : 'bar',
837+
'ItemC' : 'baz'
838+
}
839+
840+
renamed = self.panel.rename_axis(mapper, axis=0)
841+
exp = Index(['foo', 'bar', 'baz'])
842+
self.assert_(renamed.items.equals(exp))
843+
844+
renamed = self.panel.rename_axis(str.lower, axis=2)
845+
exp = Index(['a', 'b', 'c', 'd'])
846+
self.assert_(renamed.minor_axis.equals(exp))
847+
848+
# don't copy
849+
renamed_nocopy = self.panel.rename_axis(mapper, axis=0, copy=False)
850+
renamed_nocopy['foo'] = 3.
851+
self.assert_((self.panel['ItemA'].values == 3).all())
852+
833853
class TestLongPanel(unittest.TestCase):
834854

835855
def setUp(self):
@@ -1149,7 +1169,6 @@ def test_pivot(self):
11491169
df = pivot(np.array([]), np.array([]), np.array([]))
11501170

11511171

1152-
11531172
def test_group_agg():
11541173
values = np.ones((10, 2)) * np.arange(10).reshape((10, 1))
11551174
bounds = np.arange(5) * 2

0 commit comments

Comments
 (0)