Skip to content

Commit 613df15

Browse files
jbrockmendeljreback
authored andcommitted
BUG: TDI/DTI _shallow_copy creating invalid arrays (pandas-dev#30764)
1 parent 8803056 commit 613df15

File tree

2 files changed

+44
-9
lines changed

2 files changed

+44
-9
lines changed

pandas/core/indexes/datetimelike.py

+25-9
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,12 @@
2828

2929
from pandas.core import algorithms
3030
from pandas.core.accessor import PandasDelegate
31-
from pandas.core.arrays import ExtensionArray, ExtensionOpsMixin
31+
from pandas.core.arrays import (
32+
DatetimeArray,
33+
ExtensionArray,
34+
ExtensionOpsMixin,
35+
TimedeltaArray,
36+
)
3237
from pandas.core.arrays.datetimelike import (
3338
DatetimeLikeArrayMixin,
3439
_ensure_datetimelike_to_i8,
@@ -251,15 +256,10 @@ def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs):
251256
if isinstance(maybe_slice, slice):
252257
return self[maybe_slice]
253258

254-
taken = ExtensionIndex.take(
259+
return ExtensionIndex.take(
255260
self, indices, axis, allow_fill, fill_value, **kwargs
256261
)
257262

258-
# keep freq in PeriodArray/Index, reset otherwise
259-
freq = self.freq if is_period_dtype(self) else None
260-
assert taken.freq == freq, (taken.freq, freq, taken)
261-
return self._shallow_copy(taken, freq=freq)
262-
263263
_can_hold_na = True
264264

265265
_na_value = NaT
@@ -486,8 +486,8 @@ def isin(self, values, level=None):
486486
@Appender(_index_shared_docs["repeat"] % _index_doc_kwargs)
487487
def repeat(self, repeats, axis=None):
488488
nv.validate_repeat(tuple(), dict(axis=axis))
489-
freq = self.freq if is_period_dtype(self) else None
490-
return self._shallow_copy(self.asi8.repeat(repeats), freq=freq)
489+
result = type(self._data)(self.asi8.repeat(repeats), dtype=self.dtype)
490+
return self._shallow_copy(result)
491491

492492
@Appender(_index_shared_docs["where"] % _index_doc_kwargs)
493493
def where(self, cond, other=None):
@@ -650,6 +650,22 @@ def _set_freq(self, freq):
650650

651651
self._data._freq = freq
652652

653+
def _shallow_copy(self, values=None, **kwargs):
654+
if values is None:
655+
values = self._data
656+
if isinstance(values, type(self)):
657+
values = values._data
658+
659+
attributes = self._get_attributes_dict()
660+
661+
if "freq" not in kwargs and self.freq is not None:
662+
if isinstance(values, (DatetimeArray, TimedeltaArray)):
663+
if values.freq is None:
664+
del attributes["freq"]
665+
666+
attributes.update(kwargs)
667+
return self._simple_new(values, **attributes)
668+
653669
# --------------------------------------------------------------------
654670
# Set Operation Methods
655671

pandas/tests/indexes/datetimes/test_constructors.py

+19
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,25 @@ def test_freq_validation_with_nat(self, dt_cls):
2929
with pytest.raises(ValueError, match=msg):
3030
dt_cls([pd.NaT, pd.Timestamp("2011-01-01").value], freq="D")
3131

32+
# TODO: better place for tests shared by DTI/TDI?
33+
@pytest.mark.parametrize(
34+
"index",
35+
[
36+
pd.date_range("2016-01-01", periods=5, tz="US/Pacific"),
37+
pd.timedelta_range("1 Day", periods=5),
38+
],
39+
)
40+
def test_shallow_copy_inherits_array_freq(self, index):
41+
# If we pass a DTA/TDA to shallow_copy and dont specify a freq,
42+
# we should inherit the array's freq, not our own.
43+
array = index._data
44+
45+
arr = array[[0, 3, 2, 4, 1]]
46+
assert arr.freq is None
47+
48+
result = index._shallow_copy(arr)
49+
assert result.freq is None
50+
3251
def test_categorical_preserves_tz(self):
3352
# GH#18664 retain tz when going DTI-->Categorical-->DTI
3453
# TODO: parametrize over DatetimeIndex/DatetimeArray

0 commit comments

Comments
 (0)