diff --git a/asv_bench/benchmarks/timeseries.py b/asv_bench/benchmarks/timeseries.py index efe713639fec9..b7151ad2eaa99 100644 --- a/asv_bench/benchmarks/timeseries.py +++ b/asv_bench/benchmarks/timeseries.py @@ -510,3 +510,17 @@ def time_begin_incr_rng(self): def time_begin_decr_rng(self): self.rng - self.semi_month_begin + + +class DatetimeAccessor(object): + def setup(self): + self.N = 100000 + self.series = pd.Series( + pd.date_range(start='1/1/2000', periods=self.N, freq='T') + ) + + def time_dt_accessor(self): + self.series.dt + + def time_dt_accessor_normalize(self): + self.series.dt.normalize() diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt index 8b2c4d16f4e1a..e21ee8d7d31f5 100644 --- a/doc/source/whatsnew/v0.21.0.txt +++ b/doc/source/whatsnew/v0.21.0.txt @@ -296,6 +296,7 @@ Performance Improvements ~~~~~~~~~~~~~~~~~~~~~~~~ - Improved performance of instantiating :class:`SparseDataFrame` (:issue:`16773`) +- :attr:`Series.dt` no longer performs frequency inference, yielding a large speedup when accessing the attribute (:issue:`17210`) .. _whatsnew_0210.bug_fixes: diff --git a/pandas/core/indexes/accessors.py b/pandas/core/indexes/accessors.py index ce3143b342cec..88297ac70984d 100644 --- a/pandas/core/indexes/accessors.py +++ b/pandas/core/indexes/accessors.py @@ -61,23 +61,20 @@ def maybe_to_datetimelike(data, copy=False): data = orig.values.categories if is_datetime64_dtype(data.dtype): - return DatetimeProperties(DatetimeIndex(data, copy=copy, freq='infer'), + return DatetimeProperties(DatetimeIndex(data, copy=copy), index, name=name, orig=orig) elif is_datetime64tz_dtype(data.dtype): - return DatetimeProperties(DatetimeIndex(data, copy=copy, freq='infer', - ambiguous='infer'), + return DatetimeProperties(DatetimeIndex(data, copy=copy), index, data.name, orig=orig) elif is_timedelta64_dtype(data.dtype): - return TimedeltaProperties(TimedeltaIndex(data, copy=copy, - freq='infer'), index, + return TimedeltaProperties(TimedeltaIndex(data, copy=copy), index, name=name, orig=orig) else: if is_period_arraylike(data): return PeriodProperties(PeriodIndex(data, copy=copy), index, name=name, orig=orig) if is_datetime_arraylike(data): - return DatetimeProperties(DatetimeIndex(data, copy=copy, - freq='infer'), index, + return DatetimeProperties(DatetimeIndex(data, copy=copy), index, name=name, orig=orig) raise TypeError("cannot convert an object of type {0} to a " @@ -162,6 +159,10 @@ class DatetimeProperties(Properties): def to_pydatetime(self): return self.values.to_pydatetime() + @property + def freq(self): + return self.values.inferred_freq + DatetimeProperties._add_delegate_accessors( delegate=DatetimeIndex, @@ -202,6 +203,10 @@ def components(self): """ return self.values.components.set_index(self.index) + @property + def freq(self): + return self.values.inferred_freq + TimedeltaProperties._add_delegate_accessors( delegate=TimedeltaIndex,