-
-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
API: Deprecate renamae_axis and reindex_axis #17842
Changes from 7 commits
8c54f26
9776ada
d4baabf
f40875b
1d1c269
9e915f9
50499e4
a92f492
c780537
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,7 +29,8 @@ | |
from pandas.core.dtypes.missing import isna, notna | ||
from pandas.core.dtypes.generic import ABCSeries, ABCPanel, ABCDataFrame | ||
|
||
from pandas.core.common import (_values_from_object, | ||
from pandas.core.common import (_all_not_none, | ||
_values_from_object, | ||
_maybe_box_datetimelike, | ||
SettingWithCopyError, SettingWithCopyWarning, | ||
AbstractMethodError) | ||
|
@@ -729,6 +730,51 @@ def swaplevel(self, i=-2, j=-1, axis=0): | |
result._data.set_axis(axis, labels.swaplevel(i, j)) | ||
return result | ||
|
||
def _validate_axis_style_args(self, arg, arg_name, axes, | ||
axis, method_name): | ||
out = {} | ||
for i, value in enumerate(axes): | ||
if value is not None: | ||
out[self._AXIS_NAMES[i]] = value | ||
|
||
aliases = ', '.join(self._AXIS_NAMES.values()) | ||
if axis is not None: | ||
# Using "axis" style, along with a positional arg | ||
# Both index and columns should be None then | ||
axis = self._get_axis_name(axis) | ||
if any(x is not None for x in axes): | ||
msg = ( | ||
"Can't specify both 'axis' and {aliases}" | ||
"Specify either\n" | ||
"\t.{method_name}({arg_name}, axis=axis), or\n" | ||
"\t.{method_name}(index=index, columns=columns)" # TODO | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does your 'todo' point to the fact that "index=index, columns=columns" is not generic for all NDFrame types ? (like Panels) If that is the case, I personally wouldn't care. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, I'll happily ignore :) |
||
).format(arg_name=arg_name, method_name=method_name, | ||
aliases=aliases) | ||
raise TypeError(msg) | ||
out[axis] = arg | ||
|
||
elif _all_not_none(arg, *axes): | ||
msg = ( | ||
"Cannot specify all of '{arg_name}', {aliases}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also missing ". " |
||
"Specify either {arg_name} and 'axis', or {aliases}." | ||
).format(arg_name=arg_name, aliases=aliases) | ||
raise TypeError(msg) | ||
|
||
elif _all_not_none(arg, axes[0]): | ||
# This is the "ambiguous" case, so emit a warning | ||
msg = ( | ||
"Interpreting call to '.{method_name}(a, b)' as " | ||
"'.{method_name}(index=a, columns=b)'. " # TODO | ||
"Use keyword arguments to remove any ambiguity." | ||
).format(method_name=method_name) | ||
warnings.warn(msg, stacklevel=3) | ||
out[self._AXIS_ORDERS[0]] = arg | ||
out[self._AXIS_ORDERS[1]] = axes[0] | ||
elif axes[0] is None: | ||
# This is for the default axis, like reindex([0, 1]) | ||
out[self._AXIS_ORDERS[0]] = arg | ||
return out | ||
|
||
# ---------------------------------------------------------------------- | ||
# Rename | ||
|
||
|
@@ -893,17 +939,12 @@ def f(x): | |
rename.__doc__ = _shared_docs['rename'] | ||
|
||
def rename_axis(self, mapper, axis=0, copy=True, inplace=False): | ||
""" | ||
Alter index and / or columns using input function or functions. | ||
A scalar or list-like for ``mapper`` will alter the ``Index.name`` | ||
or ``MultiIndex.names`` attribute. | ||
A function or dict for ``mapper`` will alter the labels. | ||
Function / dict values must be unique (1-to-1). Labels not contained in | ||
a dict / Series will be left as-is. | ||
"""Alter the name of the index or columns. | ||
|
||
Parameters | ||
---------- | ||
mapper : scalar, list-like, dict-like or function, optional | ||
mapper : scalar, list-like, optional | ||
Value to set the axis name attribute. | ||
axis : int or string, default 0 | ||
copy : boolean, default True | ||
Also copy underlying data | ||
|
@@ -913,38 +954,45 @@ def rename_axis(self, mapper, axis=0, copy=True, inplace=False): | |
------- | ||
renamed : type of caller or None if inplace=True | ||
|
||
Notes | ||
----- | ||
Prior to version 0.21.0, ``rename_axis`` could also be used to change | ||
the axis *labels* by passing a mapping or scalar. This behavior is | ||
deprecated and will be removed in a future version. Use ``rename`` | ||
instead. | ||
|
||
See Also | ||
-------- | ||
pandas.NDFrame.rename | ||
pandas.Series.rename, pandas.DataFrame.rename | ||
pandas.Index.rename | ||
|
||
Examples | ||
-------- | ||
|
||
>>> df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}) | ||
>>> df.rename_axis("foo") # scalar, alters df.index.name | ||
>>> df.rename_axis("foo") | ||
A B | ||
foo | ||
0 1 4 | ||
1 2 5 | ||
2 3 6 | ||
>>> df.rename_axis(lambda x: 2 * x) # function: alters labels | ||
A B | ||
0 1 4 | ||
2 2 5 | ||
4 3 6 | ||
>>> df.rename_axis({"A": "ehh", "C": "see"}, axis="columns") # mapping | ||
ehh B | ||
|
||
>>> df.rename_axis("bar", axis="columns") | ||
bar A B | ||
0 1 4 | ||
1 2 5 | ||
2 3 6 | ||
|
||
""" | ||
inplace = validate_bool_kwarg(inplace, 'inplace') | ||
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, inplace=inplace) | ||
else: | ||
msg = ("Using 'rename_axis' to alter labels is deprecated. " | ||
"Use '.rename' instead") | ||
warnings.warn(msg, FutureWarning, stacklevel=2) | ||
axis = self._get_axis_name(axis) | ||
d = {'copy': copy, 'inplace': inplace} | ||
d[axis] = mapper | ||
|
@@ -2981,6 +3029,11 @@ def reindex(self, *args, **kwargs): | |
tolerance = kwargs.pop('tolerance', None) | ||
fill_value = kwargs.pop('fill_value', np.nan) | ||
|
||
# Series.reindex doesn't use / need the axis kwarg | ||
# We pop and ignore it here, to make writing Series/Frame generic code | ||
# easier | ||
kwargs.pop("axis", None) | ||
|
||
if kwargs: | ||
raise TypeError('reindex() got an unexpected keyword ' | ||
'argument "{0}"'.format(list(kwargs.keys())[0])) | ||
|
@@ -3085,11 +3138,14 @@ def _reindex_multi(self, axes, copy, fill_value): | |
@Appender(_shared_docs['reindex_axis'] % _shared_doc_kwargs) | ||
def reindex_axis(self, labels, axis=0, method=None, level=None, copy=True, | ||
limit=None, fill_value=np.nan): | ||
msg = ("'.reindex_axis' is deprecated and will be removed in a future " | ||
"version. Use '.reindex' instead.") | ||
self._consolidate_inplace() | ||
|
||
axis_name = self._get_axis_name(axis) | ||
axis_values = self._get_axis(axis_name) | ||
method = missing.clean_reindex_fill_method(method) | ||
warnings.warn(msg, FutureWarning, stacklevel=3) | ||
new_index, indexer = axis_values.reindex(labels, method, level, | ||
limit=limit) | ||
return self._reindex_with_indexers({axis: [new_index, indexer]}, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1197,13 +1197,20 @@ def _wrap_result(self, result, axis): | |
return self._construct_return_type(result, axes) | ||
|
||
@Appender(_shared_docs['reindex'] % _shared_doc_kwargs) | ||
def reindex(self, items=None, major_axis=None, minor_axis=None, **kwargs): | ||
def reindex(self, labels=None, | ||
items=None, major_axis=None, minor_axis=None, | ||
axis=None, **kwargs): | ||
major_axis = (major_axis if major_axis is not None else | ||
kwargs.pop('major', None)) | ||
minor_axis = (minor_axis if minor_axis is not None else | ||
kwargs.pop('minor', None)) | ||
return super(Panel, self).reindex(items=items, major_axis=major_axis, | ||
minor_axis=minor_axis, **kwargs) | ||
axes = self._validate_axis_style_args( | ||
labels, 'labels', axes=[items, major_axis, minor_axis], | ||
axis=axis, method_name='reindex') | ||
if self.ndim >= 4: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I got a bit annoyed with PanelND :) I think this is acceptable until we remove it. |
||
# Hack for PanelND | ||
axes = {} | ||
return super(Panel, self).reindex(**axes, **kwargs) | ||
|
||
@Appender(_shared_docs['rename'] % _shared_doc_kwargs) | ||
def rename(self, items=None, major_axis=None, minor_axis=None, **kwargs): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add ". " at the end of this string? (point + space)