Skip to content

REF: avoid Period.freq #52549

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 4 commits into from
Apr 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pandas/_libs/tslibs/period.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ from typing import Literal

import numpy as np

from pandas._libs.tslibs.dtypes import PeriodDtypeBase
from pandas._libs.tslibs.nattype import NaTType
from pandas._libs.tslibs.offsets import BaseOffset
from pandas._libs.tslibs.timestamps import Timestamp
Expand Down Expand Up @@ -67,6 +68,7 @@ class PeriodMixin:
class Period(PeriodMixin):
ordinal: int # int64_t
freq: BaseOffset
_dtype: PeriodDtypeBase

# error: "__new__" must return a class instance (got "Union[Period, NaTType]")
def __new__( # type: ignore[misc]
Expand Down
8 changes: 4 additions & 4 deletions pandas/_libs/tslibs/period.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1711,7 +1711,7 @@ cdef class _Period(PeriodMixin):

def __richcmp__(self, other, op):
if is_period_object(other):
if other.freq != self.freq:
if other._dtype != self._dtype:
if op == Py_EQ:
return False
elif op == Py_NE:
Expand Down Expand Up @@ -1781,7 +1781,7 @@ cdef class _Period(PeriodMixin):
elif other is NaT:
return NaT
elif util.is_integer_object(other):
ordinal = self.ordinal + other * self.freq.n
ordinal = self.ordinal + other * self._dtype._n
return Period(ordinal=ordinal, freq=self.freq)

elif is_period_object(other):
Expand Down Expand Up @@ -1866,7 +1866,7 @@ cdef class _Period(PeriodMixin):
# self.n can't be negative or 0
end = how == "E"
if end:
ordinal = self.ordinal + self.freq.n - 1
ordinal = self.ordinal + self._dtype._n - 1
else:
ordinal = self.ordinal
ordinal = period_asfreq(ordinal, base1, base2, end)
Expand Down Expand Up @@ -2630,7 +2630,7 @@ class Period(_Period):

elif is_period_object(value):
other = value
if freq is None or freq._period_dtype_code == other.freq._period_dtype_code:
if freq is None or freq._period_dtype_code == other._dtype._dtype_code:
ordinal = other.ordinal
freq = other.freq
else:
Expand Down
8 changes: 4 additions & 4 deletions pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -1309,7 +1309,7 @@ def __add__(self, other):
if not isinstance(self.dtype, PeriodDtype):
raise integer_op_not_supported(self)
obj = cast("PeriodArray", self)
result = obj._addsub_int_array_or_scalar(other * obj.freq.n, operator.add)
result = obj._addsub_int_array_or_scalar(other * obj.dtype._n, operator.add)

# array-like others
elif is_timedelta64_dtype(other_dtype):
Expand All @@ -1327,7 +1327,7 @@ def __add__(self, other):
if not isinstance(self.dtype, PeriodDtype):
raise integer_op_not_supported(self)
obj = cast("PeriodArray", self)
result = obj._addsub_int_array_or_scalar(other * obj.freq.n, operator.add)
result = obj._addsub_int_array_or_scalar(other * obj.dtype._n, operator.add)
else:
# Includes Categorical, other ExtensionArrays
# For PeriodDtype, if self is a TimedeltaArray and other is a
Expand Down Expand Up @@ -1367,7 +1367,7 @@ def __sub__(self, other):
if not isinstance(self.dtype, PeriodDtype):
raise integer_op_not_supported(self)
obj = cast("PeriodArray", self)
result = obj._addsub_int_array_or_scalar(other * obj.freq.n, operator.sub)
result = obj._addsub_int_array_or_scalar(other * obj.dtype._n, operator.sub)

elif isinstance(other, Period):
result = self._sub_periodlike(other)
Expand All @@ -1391,7 +1391,7 @@ def __sub__(self, other):
if not isinstance(self.dtype, PeriodDtype):
raise integer_op_not_supported(self)
obj = cast("PeriodArray", self)
result = obj._addsub_int_array_or_scalar(other * obj.freq.n, operator.sub)
result = obj._addsub_int_array_or_scalar(other * obj.dtype._n, operator.sub)
else:
# Includes ExtensionArrays, float_dtype
return NotImplemented
Expand Down
6 changes: 3 additions & 3 deletions pandas/core/arrays/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@

def _field_accessor(name: str, docstring: str | None = None):
def f(self):
base = self.freq._period_dtype_code
base = self.dtype._dtype_code
result = get_period_field_arr(name, self.asi8, base)
return result

Expand Down Expand Up @@ -543,7 +543,7 @@ def to_timestamp(self, freq=None, how: str = "start") -> DatetimeArray:
diffs = libalgos.unique_deltas(self.asi8)
if len(diffs) == 1:
diff = diffs[0]
if diff == self.freq.n:
if diff == self.dtype._n:
dta._freq = self.freq
elif diff == 1:
dta._freq = self.freq.base
Expand Down Expand Up @@ -614,7 +614,7 @@ def asfreq(self, freq=None, how: str = "E") -> Self:
# self.freq.n can't be negative or 0
end = how == "E"
if end:
ordinal = asi8 + self.freq.n - 1
ordinal = asi8 + self.dtype._n - 1
else:
ordinal = asi8

Expand Down
13 changes: 1 addition & 12 deletions pandas/core/indexes/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,18 +435,7 @@ def get_loc(self, key):
raise KeyError(orig_key) from err

def _disallow_mismatched_indexing(self, key: Period) -> None:
sfreq = self.freq
kfreq = key.freq
if not (
sfreq.n == kfreq.n
# error: "BaseOffset" has no attribute "_period_dtype_code"
and sfreq._period_dtype_code # type: ignore[attr-defined]
# error: "BaseOffset" has no attribute "_period_dtype_code"
== kfreq._period_dtype_code # type: ignore[attr-defined]
):
# GH#42247 For the subset of DateOffsets that can be Period freqs,
# checking these two attributes is sufficient to check equality,
# and much more performant than `self.freq == key.freq`
if key._dtype != self.dtype:
raise KeyError(key)

def _cast_partial_indexing_scalar(self, label: datetime) -> Period:
Expand Down