Skip to content

Commit 3af6109

Browse files
committed
WIP: change data
1 parent e16dd61 commit 3af6109

File tree

7 files changed

+44
-20
lines changed

7 files changed

+44
-20
lines changed

pandas/core/arrays/datetimelike.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
import pandas.core.common as com
4444
from pandas.core.algorithms import checked_add_with_arr
4545

46-
from .base import ExtensionOpsMixin
46+
from .base import ExtensionOpsMixin, ExtensionArray
4747
from pandas.util._decorators import deprecate_kwarg
4848

4949

@@ -270,7 +270,7 @@ def ceil(self, freq, ambiguous='raise', nonexistent='raise'):
270270
return self._round(freq, RoundTo.PLUS_INFTY, ambiguous, nonexistent)
271271

272272

273-
class DatetimeLikeArrayMixin(DatelikeOps, TimelikeOps, AttributesMixin):
273+
class DatetimeLikeArrayMixin(DatelikeOps, TimelikeOps, AttributesMixin, ExtensionArray):
274274
"""
275275
Shared Base/Mixin class for DatetimeArray, TimedeltaArray, PeriodArray
276276

pandas/core/arrays/datetimes.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ def _simple_new(cls, values, freq=None, tz=None, **kwargs):
209209
return result
210210

211211
def __new__(cls, values, freq=None, tz=None, dtype=None):
212+
if isinstance(values, (ABCSeries, ABCIndexClass)):
213+
values = values._values
214+
212215
if tz is None and hasattr(values, 'tz'):
213216
# e.g. DatetimeIndex
214217
tz = values.tz
@@ -317,7 +320,7 @@ def _generate_range(cls, start, end, periods, freq, tz=None,
317320
if not right_closed and len(index) and index[-1] == end:
318321
index = index[:-1]
319322

320-
return cls._simple_new(index.values, freq=freq, tz=tz)
323+
return cls._simple_new(index.asi8, freq=freq, tz=tz)
321324

322325
# -----------------------------------------------------------------
323326
# Descriptive Properties
@@ -389,12 +392,12 @@ def _resolution(self):
389392

390393
def __array__(self, dtype=None):
391394
if is_object_dtype(dtype):
395+
import pdb; pdb.set_trace
392396
return np.array(list(self), dtype=object)
393397
elif is_int64_dtype(dtype):
394398
return self.asi8
395399

396-
# TODO: warn that conversion may be lossy?
397-
return self._data.view(np.ndarray) # follow Index.__array__
400+
return self._data
398401

399402
def __iter__(self):
400403
"""

pandas/core/indexes/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ def __len__(self):
687687

688688
def __array__(self, dtype=None):
689689
""" the array interface, return my values """
690-
return self._data.view(np.ndarray)
690+
return np.asarray(self._data, dtype=dtype)
691691

692692
def __array_wrap__(self, result, context=None):
693693
"""

pandas/core/indexes/datetimelike.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
from pandas.core import algorithms, ops
2727
from pandas.core.accessor import PandasDelegate
28-
from pandas.core.arrays import PeriodArray, ExtensionOpsMixin
28+
from pandas.core.arrays import ExtensionOpsMixin, PeriodArray
2929
from pandas.core.arrays.datetimelike import DatetimeLikeArrayMixin
3030
import pandas.core.indexes.base as ibase
3131
from pandas.core.indexes.base import Index, _index_shared_docs
@@ -156,6 +156,8 @@ def _box_values_as_index(self):
156156
"""
157157
return object Index which contains boxed values
158158
"""
159+
# XXX: this is broken (not called) for PeriodIndex, which doesn't
160+
# define _box_values AFAICT
159161
from pandas.core.index import Index
160162
return Index(self._box_values(self.asi8), name=self.name, dtype=object)
161163

@@ -705,3 +707,7 @@ def freq(self):
705707
# Can't simply use delegate_names since our base class is defining
706708
# freq
707709
return self._data.freq
710+
711+
@property
712+
def freqstr(self):
713+
return self._data.freq.freqstr

pandas/core/indexes/datetimes.py

+23-10
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from pandas._libs.tslibs import (
1414
ccalendar, conversion, fields, parsing, timezones)
1515
import pandas.compat as compat
16-
from pandas.core.accessor import delegate_names
1716
from pandas.util._decorators import Appender, Substitution, cache_readonly
1817

1918
from pandas.core.dtypes.common import (
@@ -25,15 +24,16 @@
2524
from pandas.core.dtypes.generic import ABCSeries
2625
from pandas.core.dtypes.missing import isna
2726

27+
from pandas.core.accessor import delegate_names
2828
from pandas.core.arrays import datetimelike as dtl
2929
from pandas.core.arrays.datetimes import (
3030
DatetimeArrayMixin as DatetimeArray, _to_m8)
3131
from pandas.core.base import _shared_docs
3232
import pandas.core.common as com
3333
from pandas.core.indexes.base import Index, _index_shared_docs
3434
from pandas.core.indexes.datetimelike import (
35-
DatetimeIndexOpsMixin, wrap_array_method,
36-
wrap_field_accessor, DatelikeIndexMixin, DatetimelikeDelegateMixin)
35+
DatelikeIndexMixin, DatetimeIndexOpsMixin, DatetimelikeDelegateMixin,
36+
wrap_array_method, wrap_field_accessor)
3737
from pandas.core.indexes.numeric import Int64Index
3838
from pandas.core.ops import get_op_result_name
3939
import pandas.core.tools.datetimes as tools
@@ -185,6 +185,20 @@ class DatetimeIndex(DatelikeIndexMixin,
185185
"""
186186
_typ = 'datetimeindex'
187187
_join_precedence = 10
188+
# TODO: dispatch
189+
@classmethod
190+
def _generate_range(cls, start, end, periods, freq, tz=None,
191+
normalize=False, ambiguous="raise",
192+
closed=None):
193+
return cls._simple_new(
194+
DatetimeArray._generate_range(
195+
start, end, periods, freq, tz=tz,
196+
normalize=normalize, ambiguous=ambiguous,
197+
closed=closed,
198+
)
199+
)
200+
_box_func = DatetimeArray._box_func
201+
_box_values = DatetimeArray._box_values
188202

189203
def _join_i8_wrapper(joinf, **kwargs):
190204
return DatetimeIndexOpsMixin._join_i8_wrapper(joinf, dtype='M8[ns]',
@@ -321,24 +335,23 @@ def _simple_new(cls, values, name=None, freq=None, tz=None,
321335
if we are passed a non-dtype compat, then coerce using the constructor
322336
"""
323337
# DatetimeArray._simple_new will accept either i8 or M8[ns] dtypes
324-
assert isinstance(values, np.ndarray), type(values)
338+
values = DatetimeArray(values, dtype=dtype, freq=freq, tz=tz)
339+
# assert isinstance(values, np.ndarray), type(values)
325340

326341
result = super(DatetimeIndex, cls)._simple_new(values, freq, tz,
327342
**kwargs)
328343
result.name = name
329344
result._reset_identity()
330345
return result
331346

347+
@property
348+
def values(self):
349+
return self._data._data
332350
# --------------------------------------------------------------------
333351

334352
@property
335353
def _values(self):
336-
# tz-naive -> ndarray
337-
# tz-aware -> DatetimeIndex
338-
if self.tz is not None:
339-
return self
340-
else:
341-
return self.values
354+
return self._data
342355

343356
@property
344357
def tz(self):

pandas/core/indexes/timedeltas.py

+2
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ class TimedeltaIndex(TimedeltaDelegateMixin,
110110

111111
_typ = 'timedeltaindex'
112112
_join_precedence = 10
113+
# TODO: dispatch
114+
_generate_range = TimedeltaArray._generate_range
113115

114116
def _join_i8_wrapper(joinf, **kwargs):
115117
return DatetimeIndexOpsMixin._join_i8_wrapper(

pandas/tests/arrays/test_datetimelike.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def test_to_period(self, datetime_index, freqstr):
153153
# an EA-specific tm.assert_ function
154154
tm.assert_index_equal(pd.Index(result), pd.Index(expected))
155155

156-
@pytest.mark.parametrize('propname', pd.DatetimeIndex._bool_ops)
156+
@pytest.mark.parametrize('propname', pd.core.arrays.DatetimeArrayMixin._bool_ops)
157157
def test_bool_properties(self, datetime_index, propname):
158158
# in this case _bool_ops is just `is_leap_year`
159159
dti = datetime_index
@@ -165,7 +165,7 @@ def test_bool_properties(self, datetime_index, propname):
165165

166166
tm.assert_numpy_array_equal(result, expected)
167167

168-
@pytest.mark.parametrize('propname', pd.DatetimeIndex._field_ops)
168+
@pytest.mark.parametrize('propname', pd.core.arrays.DatetimeArrayMixin._field_ops)
169169
def test_int_properties(self, datetime_index, propname):
170170
dti = datetime_index
171171
arr = DatetimeArray(dti)
@@ -213,7 +213,7 @@ def test_total_seconds(self, timedelta_index):
213213

214214
tm.assert_numpy_array_equal(result, expected.values)
215215

216-
@pytest.mark.parametrize('propname', pd.TimedeltaIndex._field_ops)
216+
@pytest.mark.parametrize('propname', pd.core.arrays.TimedeltaArrayMixin._field_ops)
217217
def test_int_properties(self, timedelta_index, propname):
218218
tdi = timedelta_index
219219
arr = TimedeltaArray(tdi)

0 commit comments

Comments
 (0)