From a7bce3500bebcf34f67c09da711447858f72b044 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sat, 2 Sep 2017 09:23:18 -0700 Subject: [PATCH 1/4] Remove unnecessary iNaT checks from Period properties --- pandas/_libs/period.pyx | 125 +++++++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 48 deletions(-) diff --git a/pandas/_libs/period.pyx b/pandas/_libs/period.pyx index 816b7ebfff86d..7a52d48a98618 100644 --- a/pandas/_libs/period.pyx +++ b/pandas/_libs/period.pyx @@ -105,6 +105,8 @@ cdef extern from "period_helper.h": int pday(int64_t ordinal, int freq) except INT32_MIN int pweekday(int64_t ordinal, int freq) except INT32_MIN int pday_of_week(int64_t ordinal, int freq) except INT32_MIN + # TODO: pday_of_week and pweekday are identical. Make one an alias instead + # of importing them separately. int pday_of_year(int64_t ordinal, int freq) except INT32_MIN int pweek(int64_t ordinal, int freq) except INT32_MIN int phour(int64_t ordinal, int freq) except INT32_MIN @@ -872,54 +874,81 @@ cdef class _Period(object): base, mult = frequencies.get_freq_code(self.freq) return get_period_field(alias, self.ordinal, base) - property year: - def __get__(self): - return self._field(0) - property month: - def __get__(self): - return self._field(3) - property day: - def __get__(self): - return self._field(4) - property hour: - def __get__(self): - return self._field(5) - property minute: - def __get__(self): - return self._field(6) - property second: - def __get__(self): - return self._field(7) - property weekofyear: - def __get__(self): - return self._field(8) - property week: - def __get__(self): - return self.weekofyear - property dayofweek: - def __get__(self): - return self._field(10) - property weekday: - def __get__(self): - return self.dayofweek - property dayofyear: - def __get__(self): - return self._field(9) - property quarter: - def __get__(self): - return self._field(2) - property qyear: - def __get__(self): - return self._field(1) - property days_in_month: - def __get__(self): - return self._field(11) - property daysinmonth: - def __get__(self): - return self.days_in_month - property is_leap_year: - def __get__(self): - return bool(is_leapyear(self._field(0))) + @property + def year(self): + base, mult = frequencies.get_freq_code(self.freq) + return pyear(self.ordinal, base) + + @property + def month(self): + base, mult = frequencies.get_freq_code(self.freq) + return pmonth(self.ordinal, base) + + @property + def day(self): + base, mult = frequencies.get_freq_code(self.freq) + return pday(self.ordinal, base) + + @property + def hour(self): + base, mult = frequencies.get_freq_code(self.freq) + return phour(self.ordinal, base) + + @property + def minute(self): + base, mult = frequencies.get_freq_code(self.freq) + return pminute(self.ordinal, base) + + @property + def second(self): + base, mult = frequencies.get_freq_code(self.freq) + return psecond(self.ordinal, base) + + @property + def weekofyear(self): + base, mult = frequencies.get_freq_code(self.freq) + return pweek(self.ordinal, base) + + @property + def week(self): + return self.weekofyear + + @property + def dayofweek(self): + base, mult = frequencies.get_freq_code(self.freq) + return pweekday(self.ordinal, base) + + @property + def dayofweek(self): + return self.dayofweek + + @property + def dayofyear(self): + base, mult = frequencies.get_freq_code(self.freq) + return pday_of_year(self.ordinal, base) + + @property + def quarter(self): + base, mult = frequencies.get_freq_code(self.freq) + return pquarter(self.ordinal, base) + + @property + def qyear(self): + base, mult = frequencies.get_freq_code(self.freq) + return pqyear(self.ordinal, base) + + @property + def days_in_month(self): + base, mult = frequencies.get_freq_code(self.freq) + return pdays_in_month(self.ordinal, base) + + @property + def daysinmonth(self): + return self.days_in_month + + @property + def is_leap_year(self): + return bool(is_leapyear(self.year)) @classmethod def now(cls, freq=None): From d5b67d0b18f13dd4ded633bce04e4707ef15ac2b Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sat, 2 Sep 2017 09:37:19 -0700 Subject: [PATCH 2/4] Remove unused _field method --- pandas/_libs/period.pyx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pandas/_libs/period.pyx b/pandas/_libs/period.pyx index 7a52d48a98618..54a23abdeac7e 100644 --- a/pandas/_libs/period.pyx +++ b/pandas/_libs/period.pyx @@ -870,10 +870,6 @@ cdef class _Period(object): dt64 = period_ordinal_to_dt64(val.ordinal, base) return Timestamp(dt64, tz=tz) - cdef _field(self, alias): - base, mult = frequencies.get_freq_code(self.freq) - return get_period_field(alias, self.ordinal, base) - @property def year(self): base, mult = frequencies.get_freq_code(self.freq) From df815460b95262dc68cd1805299c903e8f01d9a4 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sat, 2 Sep 2017 16:12:40 -0700 Subject: [PATCH 3/4] Fix typo duplicate dayofweek-->weekday --- pandas/_libs/period.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/_libs/period.pyx b/pandas/_libs/period.pyx index 54a23abdeac7e..300c7b9fa77ad 100644 --- a/pandas/_libs/period.pyx +++ b/pandas/_libs/period.pyx @@ -915,7 +915,7 @@ cdef class _Period(object): return pweekday(self.ordinal, base) @property - def dayofweek(self): + def weekday(self): return self.dayofweek @property From 1e0f8fb2edbb64dfbb2c85396d1d76ff8f8b4f97 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Wed, 6 Sep 2017 08:34:42 -0700 Subject: [PATCH 4/4] Add benchmarks for Period properties --- asv_bench/benchmarks/period.py | 59 ++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/asv_bench/benchmarks/period.py b/asv_bench/benchmarks/period.py index f9837191a7bae..b92a65aeccc2a 100644 --- a/asv_bench/benchmarks/period.py +++ b/asv_bench/benchmarks/period.py @@ -49,6 +49,65 @@ def time_value_counts_pindex(self): self.i.value_counts() +class Properties(object): + def setup(self): + self.per = Period('2017-09-06 08:28', freq='min') + + def time_year(self): + self.per.year + + def time_month(self): + self.per.month + + def time_day(self): + self.per.day + + def time_hour(self): + self.per.hour + + def time_minute(self): + self.per.minute + + def time_second(self): + self.per.second + + def time_is_leap_year(self): + self.per.is_leap_year + + def time_quarter(self): + self.per.quarter + + def time_qyear(self): + self.per.qyear + + def time_week(self): + self.per.week + + def time_daysinmonth(self): + self.per.daysinmonth + + def time_dayofweek(self): + self.per.dayofweek + + def time_dayofyear(self): + self.per.dayofyear + + def time_start_time(self): + self.per.start_time + + def time_end_time(self): + self.per.end_time + + def time_to_timestamp(): + self.per.to_timestamp() + + def time_now(): + self.per.now() + + def time_asfreq(): + self.per.asfreq('A') + + class period_standard_indexing(object): goal_time = 0.2