Skip to content

move rename functionality out of internals #21924

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Sep 8, 2018
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ exclude_lines =
# Don't complain if tests don't hit defensive assertion code:
raise AssertionError
raise NotImplementedError
AbstractMethodError

# Don't complain if non-runnable code isn't run:
if 0:
Expand Down
27 changes: 17 additions & 10 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,7 @@ def set_axis(a, i):
for i, a in cls._AXIS_NAMES.items():
set_axis(a, i)

# addtl parms
if isinstance(ns, dict):
for k, v in ns.items():
setattr(cls, k, v)
assert not isinstance(ns, dict)

def _construct_axes_dict(self, axes=None, **kwargs):
"""Return an axes dictionary for myself."""
Expand Down Expand Up @@ -1060,8 +1057,13 @@ def f(x):
baxis = self._get_block_manager_axis(axis)
if level is not None:
level = self.axes[axis]._get_level_number(level)
result._data = result._data.rename_axis(f, axis=baxis, copy=copy,
level=level)

# TODO: we already did a copy above, can we avoid doing again?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes it more confusing here, reaching into internals to do this.

I would rather move _transform_index and items_overlap_with_suffix from internals to Index.base (or appropriate), these are just renaming / transform helpers for an index.

Then this would be much cleaner.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes it more confusing here, reaching into internals to do this.

At least add_suffix and add_prefix are clear wins. I can de-_data this a little bit by using NDFrame.set_axis. I'll take a look at transform_index and items_overlap_with_suffix, see if there is a more reasonable place for them.

I would rather [...]

I agree, am working along similar lines.

new_data = result._data.copy(deep=copy)
from pandas.core.internals import _transform_index
new_data.set_axis(baxis,
_transform_index(new_data.axes[baxis], f, level))
result._data = new_data
result._clear_item_cache()

if inplace:
Expand Down Expand Up @@ -3330,8 +3332,10 @@ def add_prefix(self, prefix):
2 3 5
3 4 6
"""
new_data = self._data.add_prefix(prefix)
return self._constructor(new_data).__finalize__(self)
f = functools.partial('{prefix}{}'.format, prefix=prefix)

mapper = {self._info_axis_name: f}
return self.rename(**mapper)

def add_suffix(self, suffix):
"""
Expand Down Expand Up @@ -3387,8 +3391,10 @@ def add_suffix(self, suffix):
2 3 5
3 4 6
"""
new_data = self._data.add_suffix(suffix)
return self._constructor(new_data).__finalize__(self)
f = functools.partial('{}{suffix}'.format, suffix=suffix)

mapper = {self._info_axis_name: f}
return self.rename(**mapper)

_shared_docs['sort_values'] = """
Sort by the values along either axis
Expand Down Expand Up @@ -3904,6 +3910,7 @@ def _reindex_with_indexers(self, reindexers, fill_value=None, copy=False,

return self._constructor(new_data).__finalize__(self)

# TODO: unused; remove?
def _reindex_axis(self, new_index, fill_method, axis, copy):
new_data = self._data.reindex_axis(new_index, axis=axis,
method=fill_method, copy=copy)
Expand Down
34 changes: 4 additions & 30 deletions pandas/core/internals.py
Original file line number Diff line number Diff line change
Expand Up @@ -3332,30 +3332,6 @@ def set_axis(self, axis, new_labels):

self.axes[axis] = new_labels

def rename_axis(self, mapper, axis, copy=True, level=None):
"""
Rename one of axes.

Parameters
----------
mapper : unary callable
axis : int
copy : boolean, default True
level : int, default None

"""
obj = self.copy(deep=copy)
obj.set_axis(axis, _transform_index(self.axes[axis], mapper, level))
return obj

def add_prefix(self, prefix):
f = partial('{prefix}{}'.format, prefix=prefix)
return self.rename_axis(f, axis=0)

def add_suffix(self, suffix):
f = partial('{}{suffix}'.format, suffix=suffix)
return self.rename_axis(f, axis=0)

@property
def _is_single_block(self):
if self.ndim == 1:
Expand Down Expand Up @@ -3388,12 +3364,10 @@ def _rebuild_blknos_and_blklocs(self):
self._blknos = new_blknos
self._blklocs = new_blklocs

# make items read only for now
def _get_items(self):
@property
def items(self):
return self.axes[0]

items = property(fget=_get_items)

def _get_counts(self, f):
""" return a dict of the counts of the function in BlockManager """
self._consolidate_inplace()
Expand Down Expand Up @@ -4694,7 +4668,7 @@ def _block(self):
return self.blocks[0]

@property
def _values(self):
def _values(self): # TODO: unused; remove?
return self._block.values

@property
Expand Down Expand Up @@ -4762,7 +4736,7 @@ def get_values(self):
return np.array(self._block.to_dense(), copy=False)

@property
def asobject(self):
def asobject(self): # TODO: unused; remove?
"""
return a object dtype array. datetime/timedelta like values are boxed
to Timestamp/Timedelta instances.
Expand Down