-
-
Notifications
You must be signed in to change notification settings - Fork 18.7k
REF: Stop mixing DTA/TDA into DTI/TDI #24476
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
Changes from 1 commit
350b0ec
837c16a
e28ff51
ba61a0d
fdf1770
ed9e1de
ea3965d
8ceab31
5b95d78
60cd35d
bbbd778
238b386
9d01424
a5e5d65
21833f3
1ff0c4d
3faed22
e607edd
38e4bca
2afd6ab
43a162e
9ddf4bd
11dcef0
6627f56
f6a8951
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ | |
import pandas.core.dtypes.concat as _concat | ||
from pandas.core.dtypes.missing import isna | ||
|
||
from pandas.core.arrays import ExtensionOpsMixin | ||
from pandas.core.arrays.datetimes import ( | ||
DatetimeArrayMixin as DatetimeArray, _to_m8) | ||
from pandas.core.base import _shared_docs | ||
|
@@ -61,7 +62,7 @@ def _new_DatetimeIndex(cls, d): | |
return result | ||
|
||
|
||
class DatetimeIndex(DatetimeArray, DatetimeIndexOpsMixin, Int64Index): | ||
class DatetimeIndex(DatetimeIndexOpsMixin, Int64Index, ExtensionOpsMixin): | ||
""" | ||
Immutable ndarray of datetime64 data, represented internally as int64, and | ||
which can be boxed to Timestamp objects that are subclasses of datetime and | ||
|
@@ -205,6 +206,7 @@ def _join_i8_wrapper(joinf, **kwargs): | |
_object_ops = DatetimeArray._object_ops | ||
_field_ops = DatetimeArray._field_ops | ||
_datetimelike_ops = DatetimeArray._datetimelike_ops | ||
_datetimelike_methods = DatetimeArray._datetimelike_methods | ||
|
||
# -------------------------------------------------------------------- | ||
# Constructors | ||
|
@@ -227,11 +229,12 @@ def __new__(cls, data=None, | |
"endpoints is deprecated. Use " | ||
"`pandas.date_range` instead.", | ||
FutureWarning, stacklevel=2) | ||
result = cls._generate_range(start, end, periods, | ||
freq=freq, tz=tz, normalize=normalize, | ||
closed=closed, ambiguous=ambiguous) | ||
result.name = name | ||
return result | ||
dtarr = DatetimeArray._generate_range( | ||
start, end, periods, | ||
freq=freq, tz=tz, normalize=normalize, | ||
closed=closed, ambiguous=ambiguous) | ||
return cls._simple_new( | ||
dtarr._data, freq=dtarr.freq, tz=dtarr.tz, name=name) | ||
|
||
if is_scalar(data): | ||
raise TypeError("{cls}() must be called with a " | ||
|
@@ -267,7 +270,11 @@ def _simple_new(cls, values, name=None, freq=None, tz=None, dtype=None): | |
# DatetimeArray._simple_new will accept either i8 or M8[ns] dtypes | ||
assert isinstance(values, np.ndarray), type(values) | ||
|
||
result = super(DatetimeIndex, cls)._simple_new(values, freq, tz) | ||
dtarr = DatetimeArray._simple_new(values, freq=freq, tz=tz) | ||
result = object.__new__(cls) | ||
result._data = dtarr._data | ||
result._freq = dtarr.freq | ||
result._tz = dtarr.tz | ||
result.name = name | ||
# For groupby perf. See note in indexes/base about _index_data | ||
result._index_data = result._data | ||
|
@@ -281,6 +288,10 @@ def _eadata(self): | |
return DatetimeArray._simple_new(self._data, tz=self.tz, | ||
freq=self.freq) | ||
|
||
@property | ||
def dtype(self): | ||
return self._eadata.dtype | ||
|
||
@property | ||
def _values(self): | ||
# tz-naive -> ndarray | ||
|
@@ -301,6 +312,8 @@ def tz(self, value): | |
raise AttributeError("Cannot directly set timezone. Use tz_localize() " | ||
"or tz_convert() as appropriate") | ||
|
||
tzinfo = tz | ||
|
||
@property | ||
def size(self): | ||
# TODO: Remove this when we have a DatetimeTZArray | ||
|
@@ -625,7 +638,7 @@ def astype(self, dtype, copy=True): | |
def _get_time_micros(self): | ||
values = self.asi8 | ||
if self.tz is not None and not timezones.is_utc(self.tz): | ||
values = self._local_timestamps() | ||
values = self._eadata._local_timestamps() | ||
return fields.get_time_micros(values) | ||
|
||
def to_series(self, keep_tz=None, index=None, name=None): | ||
|
@@ -1138,6 +1151,97 @@ def slice_indexer(self, start=None, end=None, step=None, kind=None): | |
month_name = wrap_array_method(DatetimeArray.month_name, True) | ||
day_name = wrap_array_method(DatetimeArray.day_name, True) | ||
|
||
@property | ||
def date(self): | ||
return self._eadata.date | ||
|
||
@property | ||
def time(self): | ||
return self._eadata.time | ||
|
||
@property | ||
def timetz(self): | ||
return self._eadata.timetz | ||
|
||
def strftime(self, date_format): | ||
return self._eadata.strftime(date_format) | ||
|
||
def round(self, freq, ambiguous='raise', nonexistent='raise'): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like you can (maybe?) remove road, floor, and ciel. I haven't run the tests, but a manual example works. They should be dispatched via There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. excellent, I'll give it a shot There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. did this work out? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tentatively yes. we'll see if the CI agrees in a bit There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep |
||
result = self._eadata.round( | ||
freq, ambiguous=ambiguous, nonexistent=nonexistent) | ||
return type(self)._simple_new( | ||
result._data, freq=result.freq, tz=result.tz) | ||
|
||
def floor(self, freq, ambiguous='raise', nonexistent='raise'): | ||
result = self._eadata.floor( | ||
freq, ambiguous=ambiguous, nonexistent=nonexistent) | ||
return type(self)._simple_new( | ||
result._data, freq=result.freq, tz=result.tz) | ||
|
||
def ceil(self, freq, ambiguous='raise', nonexistent='raise'): | ||
result = self._eadata.ceil( | ||
freq, ambiguous=ambiguous, nonexistent=nonexistent) | ||
return type(self)._simple_new( | ||
result._data, freq=result.freq, tz=result.tz) | ||
|
||
@property | ||
def offset(self): | ||
""" | ||
get/set the frequency of the instance | ||
""" | ||
msg = ('{cls}.offset has been deprecated and will be removed ' | ||
'in a future version; use {cls}.freq instead.' | ||
.format(cls=type(self).__name__)) | ||
warnings.warn(msg, FutureWarning, stacklevel=2) | ||
return self.freq | ||
|
||
@offset.setter | ||
def offset(self, value): | ||
""" | ||
get/set the frequency of the instance | ||
""" | ||
msg = ('{cls}.offset has been deprecated and will be removed ' | ||
'in a future version; use {cls}.freq instead.' | ||
.format(cls=type(self).__name__)) | ||
warnings.warn(msg, FutureWarning, stacklevel=2) | ||
self.freq = value | ||
|
||
@property | ||
def freq(self): | ||
return self._freq | ||
|
||
@freq.setter | ||
def freq(self, value): | ||
if value is not None: | ||
# let DatetimeArray to validation | ||
self._eadata.freq = value | ||
|
||
self._freq = to_offset(value) | ||
|
||
def __getitem__(self, key): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In #24024 we move |
||
result = self._eadata.__getitem__(key) | ||
if is_scalar(result): | ||
return result | ||
elif result.ndim > 1: | ||
# To support MPL which performs slicing with 2 dim | ||
# even though it only has 1 dim by definition | ||
assert isinstance(result, np.ndarray), result | ||
return result | ||
return type(self)(result, name=self.name) | ||
|
||
def _has_same_tz(self, other): | ||
return self._eadata._has_same_tz(other) | ||
|
||
@property | ||
def _box_func(self): | ||
return lambda x: Timestamp(x, tz=self.tz) | ||
|
||
def __array__(self, dtype=None): | ||
return self._eadata.__array__(dtype=dtype) | ||
|
||
def to_pydatetime(self): | ||
return self._eadata.to_pydatetime() | ||
|
||
# -------------------------------------------------------------------- | ||
|
||
@Substitution(klass='DatetimeIndex') | ||
|
@@ -1475,13 +1579,12 @@ def date_range(start=None, end=None, periods=None, freq=None, tz=None, | |
if freq is None and com._any_none(periods, start, end): | ||
freq = 'D' | ||
|
||
result = DatetimeIndex._generate_range( | ||
dtarr = DatetimeArray._generate_range( | ||
start=start, end=end, periods=periods, | ||
freq=freq, tz=tz, normalize=normalize, | ||
closed=closed, **kwargs) | ||
|
||
result.name = name | ||
return result | ||
return DatetimeIndex._simple_new( | ||
dtarr._data, tz=dtarr.tz, freq=dtarr.freq, name=name) | ||
|
||
|
||
def bdate_range(start=None, end=None, periods=None, freq='B', tz=None, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should the warning message actually be in DTA._generate_range?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the non-deprecated way it gets called is via date_range