Skip to content

Commit 560190e

Browse files
jbrockmendelTomAugspurger
authored andcommitted
Modernize indexes.timedeltas, indexes.datetimeindex (#18161)
(cherry picked from commit 079f678)
1 parent c3c0b26 commit 560190e

File tree

2 files changed

+35
-51
lines changed

2 files changed

+35
-51
lines changed

pandas/core/indexes/datetimes.py

+4-11
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
from __future__ import division
33
import operator
44
import warnings
5-
from datetime import time, datetime
6-
from datetime import timedelta
5+
from datetime import time, datetime, timedelta
6+
77
import numpy as np
8+
from pytz import utc
9+
810
from pandas.core.base import _shared_docs
911

1012
from pandas.core.dtypes.common import (
@@ -55,18 +57,13 @@
5557
from pandas._libs.tslibs import timezones
5658

5759

58-
def _utc():
59-
import pytz
60-
return pytz.utc
61-
6260
# -------- some conversion wrapper functions
6361

6462

6563
def _field_accessor(name, field, docstring=None):
6664
def f(self):
6765
values = self.asi8
6866
if self.tz is not None:
69-
utc = _utc()
7067
if self.tz is not utc:
7168
values = self._local_timestamps()
7269

@@ -562,8 +559,6 @@ def _convert_for_op(self, value):
562559
raise ValueError('Passed item and index have different timezone')
563560

564561
def _local_timestamps(self):
565-
utc = _utc()
566-
567562
if self.is_monotonic:
568563
return libts.tz_convert(self.asi8, utc, self.tz)
569564
else:
@@ -823,7 +818,6 @@ def _add_delta(self, delta):
823818

824819
tz = 'UTC' if self.tz is not None else None
825820
result = DatetimeIndex(new_values, tz=tz, name=name, freq='infer')
826-
utc = _utc()
827821
if self.tz is not None and self.tz is not utc:
828822
result = result.tz_convert(self.tz)
829823
return result
@@ -877,7 +871,6 @@ def astype(self, dtype, copy=True):
877871
raise ValueError('Cannot cast DatetimeIndex to dtype %s' % dtype)
878872

879873
def _get_time_micros(self):
880-
utc = _utc()
881874
values = self.asi8
882875
if self.tz is not None and self.tz is not utc:
883876
values = self._local_timestamps()

pandas/core/indexes/timedeltas.py

+31-40
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,26 @@
3636
join as libjoin, Timedelta, NaT, iNaT)
3737

3838

39+
def _field_accessor(name, alias, docstring=None):
40+
def f(self):
41+
if self.hasnans:
42+
result = np.empty(len(self), dtype='float64')
43+
mask = self._isnan
44+
imask = ~mask
45+
result.flat[imask] = np.array([getattr(Timedelta(val), alias)
46+
for val in self.asi8[imask]])
47+
result[mask] = np.nan
48+
else:
49+
result = np.array([getattr(Timedelta(val), alias)
50+
for val in self.asi8], dtype='int64')
51+
52+
return Index(result, name=self.name)
53+
54+
f.__name__ = name
55+
f.__doc__ = docstring
56+
return property(f)
57+
58+
3959
def _td_index_cmp(opname, nat_result=False):
4060
"""
4161
Wrap comparison operations to convert timedelta-like to timedelta64
@@ -380,46 +400,17 @@ def _format_native_types(self, na_rep=u('NaT'),
380400
nat_rep=na_rep,
381401
justify='all').get_result()
382402

383-
def _get_field(self, m):
384-
385-
values = self.asi8
386-
hasnans = self.hasnans
387-
if hasnans:
388-
result = np.empty(len(self), dtype='float64')
389-
mask = self._isnan
390-
imask = ~mask
391-
result.flat[imask] = np.array(
392-
[getattr(Timedelta(val), m) for val in values[imask]])
393-
result[mask] = np.nan
394-
else:
395-
result = np.array([getattr(Timedelta(val), m)
396-
for val in values], dtype='int64')
397-
return Index(result, name=self.name)
398-
399-
@property
400-
def days(self):
401-
""" Number of days for each element. """
402-
return self._get_field('days')
403-
404-
@property
405-
def seconds(self):
406-
""" Number of seconds (>= 0 and less than 1 day) for each element. """
407-
return self._get_field('seconds')
408-
409-
@property
410-
def microseconds(self):
411-
"""
412-
Number of microseconds (>= 0 and less than 1 second) for each
413-
element. """
414-
return self._get_field('microseconds')
415-
416-
@property
417-
def nanoseconds(self):
418-
"""
419-
Number of nanoseconds (>= 0 and less than 1 microsecond) for each
420-
element.
421-
"""
422-
return self._get_field('nanoseconds')
403+
days = _field_accessor("days", "days",
404+
" Number of days for each element. ")
405+
seconds = _field_accessor("seconds", "seconds",
406+
" Number of seconds (>= 0 and less than 1 day) "
407+
"for each element. ")
408+
microseconds = _field_accessor("microseconds", "microseconds",
409+
"\nNumber of microseconds (>= 0 and less "
410+
"than 1 second) for each\nelement. ")
411+
nanoseconds = _field_accessor("nanoseconds", "nanoseconds",
412+
"\nNumber of nanoseconds (>= 0 and less "
413+
"than 1 microsecond) for each\nelement.\n")
423414

424415
@property
425416
def components(self):

0 commit comments

Comments
 (0)