65
65
_values_from_object ,
66
66
_maybe_box_datetimelike ,
67
67
_dict_compat ,
68
+ _all_not_none ,
68
69
standardize_mapping )
69
70
from pandas .core .generic import NDFrame , _shared_docs
70
71
from pandas .core .index import (Index , MultiIndex , _ensure_index ,
111
112
optional_by = """
112
113
by : str or list of str
113
114
Name or list of names which refer to the axis items.""" ,
114
- versionadded_to_excel = '' )
115
+ versionadded_to_excel = '' ,
116
+ optional_labels = """labels : array-like, optional
117
+ New labels / index to conform the axis specified by 'axis' to.""" ,
118
+ optional_axis = """axis : int or str, optional
119
+ Axis to target. Can be either the axis name ('index', 'columns')
120
+ or number (0, 1).""" ,
121
+ )
115
122
116
123
_numeric_only_doc = """numeric_only : boolean, default None
117
124
Include only float, int, boolean data. If None, will attempt to use
@@ -2776,6 +2783,47 @@ def reindexer(value):
2776
2783
2777
2784
return np .atleast_2d (np .asarray (value ))
2778
2785
2786
+ def _validate_axis_style_args (self , arg , arg_name , index , columns ,
2787
+ axis , method_name ):
2788
+ if axis is not None :
2789
+ # Using "axis" style, along with a positional arg
2790
+ # Both index and columns should be None then
2791
+ axis = self ._get_axis_name (axis )
2792
+ if index is not None or columns is not None :
2793
+ msg = (
2794
+ "Can't specify both 'axis' and 'index' or 'columns'. "
2795
+ "Specify either\n "
2796
+ "\t .{method_name}.rename({arg_name}, axis=axis), or\n "
2797
+ "\t .{method_name}.rename(index=index, columns=columns)"
2798
+ ).format (arg_name = arg_name , method_name = method_name )
2799
+ raise TypeError (msg )
2800
+ if axis == 'index' :
2801
+ index = arg
2802
+ elif axis == 'columns' :
2803
+ columns = arg
2804
+
2805
+ elif _all_not_none (arg , index , columns ):
2806
+ msg = (
2807
+ "Cannot specify all of '{arg_name}', 'index', and 'columns'. "
2808
+ "Specify either {arg_name} and 'axis', or 'index' and "
2809
+ "'columns'."
2810
+ ).format (arg_name = arg_name )
2811
+ raise TypeError (msg )
2812
+
2813
+ elif _all_not_none (arg , index ):
2814
+ # This is the "ambiguous" case, so emit a warning
2815
+ msg = (
2816
+ "Interpreting call to '.{method_name}(a, b)' as "
2817
+ "'.{method_name}(index=a, columns=b)'. "
2818
+ "Use keyword arguments to remove any ambiguity."
2819
+ ).format (method_name = method_name )
2820
+ warnings .warn (msg , stacklevel = 3 )
2821
+ index , columns = arg , index
2822
+ elif index is None :
2823
+ # This is for the default axis, like reindex([0, 1])
2824
+ index = arg
2825
+ return index , columns
2826
+
2779
2827
@property
2780
2828
def _series (self ):
2781
2829
result = {}
@@ -2902,7 +2950,11 @@ def align(self, other, join='outer', axis=None, level=None, copy=True,
2902
2950
broadcast_axis = broadcast_axis )
2903
2951
2904
2952
@Appender (_shared_docs ['reindex' ] % _shared_doc_kwargs )
2905
- def reindex (self , index = None , columns = None , ** kwargs ):
2953
+ def reindex (self , labels = None , index = None , columns = None , axis = None ,
2954
+ ** kwargs ):
2955
+ index , columns = self ._validate_axis_style_args (labels , 'labels' ,
2956
+ index , columns ,
2957
+ axis , 'reindex' )
2906
2958
return super (DataFrame , self ).reindex (index = index , columns = columns ,
2907
2959
** kwargs )
2908
2960
@@ -2914,8 +2966,84 @@ def reindex_axis(self, labels, axis=0, method=None, level=None, copy=True,
2914
2966
method = method , level = level , copy = copy ,
2915
2967
limit = limit , fill_value = fill_value )
2916
2968
2917
- @Appender (_shared_docs ['rename' ] % _shared_doc_kwargs )
2918
- def rename (self , index = None , columns = None , ** kwargs ):
2969
+ def rename (self , mapper = None , index = None , columns = None , axis = None ,
2970
+ ** kwargs ):
2971
+ """Alter axes labels.
2972
+
2973
+ Function / dict values must be unique (1-to-1). Labels not contained in
2974
+ a dict / Series will be left as-is. Extra labels listed don't throw an
2975
+ error.
2976
+
2977
+ See the :ref:`user guide <basics.rename>` for more.
2978
+
2979
+ Parameters
2980
+ ----------
2981
+ mapper, index, columns : dict-like or function, optional
2982
+ dict-like or functions transformations to apply to
2983
+ that axis' values. Use either ``mapper`` and ``axis`` to
2984
+ specify the axis to target with ``mapper``, or ``index`` and
2985
+ ``columns``.
2986
+ axis : int or str, optional
2987
+ Axis to target with ``mapper``. Can be either the axis name
2988
+ ('index', 'columns') or number (0, 1). The default is 'index'.
2989
+ copy : boolean, default True
2990
+ Also copy underlying data
2991
+ inplace : boolean, default False
2992
+ Whether to return a new %(klass)s. If True then value of copy is
2993
+ ignored.
2994
+ level : int or level name, default None
2995
+ In case of a MultiIndex, only rename labels in the specified
2996
+ level.
2997
+
2998
+ Returns
2999
+ -------
3000
+ renamed : DataFrame
3001
+
3002
+ See Also
3003
+ --------
3004
+ pandas.DataFrame.rename_axis
3005
+
3006
+ Examples
3007
+ --------
3008
+
3009
+ ``DataFrame.rename`` supports two calling conventions
3010
+
3011
+ * ``(index=index_mapper, columns=columns_mapper, ...)
3012
+ * ``(mapper, axis={'index', 'columns'}, ...)
3013
+
3014
+ We *highly* recommend using keyword arguments to clarify your
3015
+ intent.
3016
+
3017
+ >>> df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
3018
+ >>> df.rename(index=str, columns={"A": "a", "B": "c"})
3019
+ a c
3020
+ 0 1 4
3021
+ 1 2 5
3022
+ 2 3 6
3023
+
3024
+ >>> df.rename(index=str, columns={"A": "a", "C": "c"})
3025
+ a B
3026
+ 0 1 4
3027
+ 1 2 5
3028
+ 2 3 6
3029
+
3030
+ Using axis-style parameters
3031
+
3032
+ >>> df.rename(str.lower, axis='columns')
3033
+ a b
3034
+ 0 1 4
3035
+ 1 2 5
3036
+ 2 3 6
3037
+
3038
+ >>> df.rename({1: 2, 2: 4}, axis='index')
3039
+ A B
3040
+ 0 1 4
3041
+ 2 2 5
3042
+ 4 3 6
3043
+ """
3044
+ index , columns = self ._validate_axis_style_args (mapper , 'mapper' ,
3045
+ index , columns ,
3046
+ axis , 'rename' )
2919
3047
return super (DataFrame , self ).rename (index = index , columns = columns ,
2920
3048
** kwargs )
2921
3049
0 commit comments