Skip to content

Commit

Permalink
REF: _get_axis, _get_axis_name, _get_axis_number
Browse files Browse the repository at this point in the history
  • Loading branch information
topper-123 committed Apr 18, 2020
1 parent 4707d8e commit 162b954
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 51 deletions.
2 changes: 1 addition & 1 deletion pandas/core/computation/align.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def _align_core_single_unary_op(
def _zip_axes_from_type(
typ: Type[FrameOrSeries], new_axes: Sequence[int]
) -> Dict[str, int]:
axes = {name: new_axes[i] for i, name in typ._AXIS_NAMES.items()}
axes = {name: new_axes[i] for i, name in enumerate(typ._AXIS_ORDERS)}
return axes


Expand Down
19 changes: 17 additions & 2 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -8787,8 +8787,11 @@ def isin(self, values) -> "DataFrame":
# ----------------------------------------------------------------------
# Add index and columns
_AXIS_ORDERS = ["index", "columns"]
_AXIS_NUMBERS = {"index": 0, "columns": 1}
_AXIS_NAMES = {0: "index", 1: "columns"}
_AXIS_TO_AXIS_NUMBER: Dict[Axis, int] = {
**NDFrame._AXIS_TO_AXIS_NUMBER,
1: 1,
"columns": 1,
}
_AXIS_REVERSED = True
_AXIS_LEN = len(_AXIS_ORDERS)
_info_axis_number = 1
Expand All @@ -8801,6 +8804,18 @@ def isin(self, values) -> "DataFrame":
axis=0, doc="The column labels of the DataFrame."
)

@property
def _AXIS_NUMBERS(self) -> Dict[str, int]:
""".. deprecated:: 1.1.0"""
super()._AXIS_NUMBERS
return {"index": 0, "columns": 1}

@property
def _AXIS_NAMES(self) -> Dict[int, str]:
""".. deprecated:: 1.1.0"""
super()._AXIS_NAMES
return {0: "index", 1: "columns"}

# ----------------------------------------------------------------------
# Add plotting methods to DataFrame
plot = CachedAccessor("plot", pandas.plotting.PlotAccessor)
Expand Down
73 changes: 38 additions & 35 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@
is_dict_like,
is_extension_array_dtype,
is_float,
is_integer,
is_list_like,
is_number,
is_numeric_dtype,
Expand Down Expand Up @@ -302,19 +301,36 @@ def _data(self):

# ----------------------------------------------------------------------
# Axis
_AXIS_ALIASES = {"rows": 0}
_AXIS_IALIASES = {0: "rows"}
_stat_axis_number = 0
_stat_axis_name = "index"
_ix = None
_AXIS_ORDERS: List[str]
_AXIS_NUMBERS: Dict[str, int]
_AXIS_NAMES: Dict[int, str]
_AXIS_TO_AXIS_NUMBER: Dict[Axis, int] = {0: 0, "index": 0, "rows": 0}
_AXIS_REVERSED: bool
_info_axis_number: int
_info_axis_name: str
_AXIS_LEN: int

@property
def _AXIS_NUMBERS(self) -> Dict[str, int]:
""".. deprecated:: 1.1.0"""
warnings.warn(
"_AXIS_NUMBERS has been deprecated. Call ._get_axis_number instead",
FutureWarning,
stacklevel=2,
)
return {"index": 0}

@property
def _AXIS_NAMES(self) -> Dict[int, str]:
""".. deprecated:: 1.1.0"""
warnings.warn(
"_AXIS_NAMES has been deprecated. Call ._get_axis_name instead",
FutureWarning,
stacklevel=2,
)
return {0: "index"}

def _construct_axes_dict(self, axes=None, **kwargs):
"""Return an axes dictionary for myself."""
d = {a: self._get_axis(a) for a in (axes or self._AXIS_ORDERS)}
Expand Down Expand Up @@ -353,37 +369,24 @@ def _construct_axes_from_arguments(
return axes, kwargs

@classmethod
def _get_axis_number(cls, axis) -> int:
axis = cls._AXIS_ALIASES.get(axis, axis)
if is_integer(axis):
if axis in cls._AXIS_NAMES:
return axis
else:
try:
return cls._AXIS_NUMBERS[axis]
except KeyError:
pass
raise ValueError(f"No axis named {axis} for object type {cls.__name__}")
def _get_axis_number(cls, axis: Axis) -> int:
try:
return cls._AXIS_TO_AXIS_NUMBER[axis]
except KeyError:
raise ValueError(f"No axis named {axis} for object type {cls.__name__}")

@classmethod
def _get_axis_name(cls, axis) -> str:
axis = cls._AXIS_ALIASES.get(axis, axis)
if isinstance(axis, str):
if axis in cls._AXIS_NUMBERS:
return axis
else:
try:
return cls._AXIS_NAMES[axis]
except KeyError:
pass
raise ValueError(f"No axis named {axis} for object type {cls.__name__}")
def _get_axis_name(cls, axis: Axis) -> str:
axis_number = cls._get_axis_number(axis)
return cls._AXIS_ORDERS[axis_number]

def _get_axis(self, axis) -> Index:
name = self._get_axis_name(axis)
return getattr(self, name)
def _get_axis(self, axis: Axis) -> Index:
axis_number = self._get_axis_number(axis)
assert axis_number in {0, 1}
return self.index if axis_number == 0 else self.columns

@classmethod
def _get_block_manager_axis(cls, axis) -> int:
def _get_block_manager_axis(cls, axis: Axis) -> int:
"""Map the axis to the block_manager axis."""
axis = cls._get_axis_number(axis)
if cls._AXIS_REVERSED:
Expand Down Expand Up @@ -448,11 +451,11 @@ def _get_cleaned_column_resolvers(self) -> Dict[str, ABCSeries]:
}

@property
def _info_axis(self):
def _info_axis(self) -> Index:
return getattr(self, self._info_axis_name)

@property
def _stat_axis(self):
def _stat_axis(self) -> Index:
return getattr(self, self._stat_axis_name)

@property
Expand Down Expand Up @@ -813,7 +816,7 @@ def squeeze(self, axis=None):
>>> df_0a.squeeze()
1
"""
axis = self._AXIS_NAMES if axis is None else (self._get_axis_number(axis),)
axis = range(self._AXIS_LEN) if axis is None else (self._get_axis_number(axis),)
return self.iloc[
tuple(
0 if i in axis and len(a) == 1 else slice(None)
Expand Down Expand Up @@ -1156,7 +1159,7 @@ class name
result = self if inplace else self.copy(deep=copy)

for axis in range(self._AXIS_LEN):
v = axes.get(self._AXIS_NAMES[axis])
v = axes.get(self._get_axis_name(axis))
if v is lib.no_default:
continue
non_mapper = is_scalar(v) or (is_list_like(v) and not is_dict_like(v))
Expand Down
2 changes: 0 additions & 2 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -4614,8 +4614,6 @@ def to_period(self, freq=None, copy=True) -> "Series":
# ----------------------------------------------------------------------
# Add index
_AXIS_ORDERS = ["index"]
_AXIS_NUMBERS = {"index": 0}
_AXIS_NAMES = {0: "index"}
_AXIS_REVERSED = False
_AXIS_LEN = len(_AXIS_ORDERS)
_info_axis_number = 0
Expand Down
9 changes: 6 additions & 3 deletions pandas/io/json/_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -867,12 +867,15 @@ def _convert_axes(self):
"""
Try to convert axes.
"""
for axis in self.obj._AXIS_NUMBERS.keys():
for axis_name in self.obj._AXIS_ORDERS:
new_axis, result = self._try_convert_data(
axis, self.obj._get_axis(axis), use_dtypes=False, convert_dates=True
name=axis_name,
data=self.obj._get_axis(axis_name),
use_dtypes=False,
convert_dates=True,
)
if result:
setattr(self.obj, axis, new_axis)
setattr(self.obj, axis_name, new_axis)

def _try_convert_types(self):
raise AbstractMethodError(self)
Expand Down
20 changes: 15 additions & 5 deletions pandas/tests/generic/test_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -901,12 +901,22 @@ def test_pipe_tuple_error(self):
@pytest.mark.parametrize("box", [pd.Series, pd.DataFrame])
def test_axis_classmethods(self, box):
obj = box(dtype=object)
values = (
list(box._AXIS_NAMES.keys())
+ list(box._AXIS_NUMBERS.keys())
+ list(box._AXIS_ALIASES.keys())
)
values = box._AXIS_TO_AXIS_NUMBER.keys()
for v in values:
assert obj._get_axis_number(v) == box._get_axis_number(v)
assert obj._get_axis_name(v) == box._get_axis_name(v)
assert obj._get_block_manager_axis(v) == box._get_block_manager_axis(v)

@pytest.mark.parametrize("box", [pd.Series, pd.DataFrame])
def test_axis_names_deprecated(self, box):
# GH33637
obj = box(dtype=object)
with tm.assert_produces_warning(FutureWarning):
obj._AXIS_NAMES

@pytest.mark.parametrize("box", [pd.Series, pd.DataFrame])
def test_axis_numbers_deprecated(self, box):
# GH33637
obj = box(dtype=object)
with tm.assert_produces_warning(FutureWarning):
obj._AXIS_NUMBERS
6 changes: 3 additions & 3 deletions pandas/util/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ def validate_axis_style_args(data, args, kwargs, arg_name, method_name):
# like out = {'index': foo, 'columns': bar}

# Start by validating for consistency
if "axis" in kwargs and any(x in kwargs for x in data._AXIS_NUMBERS):
if "axis" in kwargs and any(x in kwargs for x in data._AXIS_TO_AXIS_NUMBER):
msg = "Cannot specify both 'axis' and any of 'index' or 'columns'."
raise TypeError(msg)

Expand Down Expand Up @@ -302,8 +302,8 @@ def validate_axis_style_args(data, args, kwargs, arg_name, method_name):
"a 'TypeError'."
)
warnings.warn(msg.format(method_name=method_name), FutureWarning, stacklevel=4)
out[data._AXIS_NAMES[0]] = args[0]
out[data._AXIS_NAMES[1]] = args[1]
out[data._get_axis_name(0)] = args[0]
out[data._get_axis_name(1)] = args[1]
else:
msg = f"Cannot specify all of '{arg_name}', 'index', 'columns'."
raise TypeError(msg)
Expand Down

0 comments on commit 162b954

Please sign in to comment.