Skip to content

Commit 4d3b197

Browse files
authored
CLN: dont special-case DatetimeArray indexing (#36654)
* CLN: dont special-case DatetimeArray indexing * use parent class _validate_getitem_key * test, whatsnew * update test
1 parent 89cc5bf commit 4d3b197

File tree

4 files changed

+28
-22
lines changed

4 files changed

+28
-22
lines changed

doc/source/whatsnew/v1.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ Indexing
393393
- Bug in :meth:`Index.get_indexer` and :meth:`Index.get_indexer_non_unique` where int64 arrays are returned instead of intp. (:issue:`36359`)
394394
- Bug in :meth:`DataFrame.sort_index` where parameter ascending passed as a list on a single level index gives wrong result. (:issue:`32334`)
395395
- Bug in :meth:`DataFrame.reset_index` was incorrectly raising a ``ValueError`` for input with a :class:`MultiIndex` with missing values in a level with ``Categorical`` dtype (:issue:`24206`)
396+
- Bug in indexing with boolean masks on datetime-like values sometimes returning a view instead of a copy (:issue:`36210`)
396397

397398
Missing
398399
^^^^^^^

pandas/core/arrays/datetimelike.py

+5-18
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
from pandas.core.arrays._mixins import NDArrayBackedExtensionArray
6666
import pandas.core.common as com
6767
from pandas.core.construction import array, extract_array
68-
from pandas.core.indexers import check_array_indexer, check_setitem_lengths
68+
from pandas.core.indexers import check_setitem_lengths
6969
from pandas.core.ops.common import unpack_zerodim_and_defer
7070
from pandas.core.ops.invalid import invalid_comparison, make_invalid_op
7171

@@ -284,23 +284,6 @@ def __getitem__(self, key):
284284
result._freq = self._get_getitem_freq(key)
285285
return result
286286

287-
def _validate_getitem_key(self, key):
288-
if com.is_bool_indexer(key):
289-
# first convert to boolean, because check_array_indexer doesn't
290-
# allow object dtype
291-
if is_object_dtype(key):
292-
key = np.asarray(key, dtype=bool)
293-
294-
key = check_array_indexer(self, key)
295-
key = lib.maybe_booleans_to_slice(key.view(np.uint8))
296-
elif isinstance(key, list) and len(key) == 1 and isinstance(key[0], slice):
297-
# see https://github.com/pandas-dev/pandas/issues/31299, need to allow
298-
# this for now (would otherwise raise in check_array_indexer)
299-
pass
300-
else:
301-
key = super()._validate_getitem_key(key)
302-
return key
303-
304287
def _get_getitem_freq(self, key):
305288
"""
306289
Find the `freq` attribute to assign to the result of a __getitem__ lookup.
@@ -322,6 +305,10 @@ def _get_getitem_freq(self, key):
322305
# GH#21282 indexing with Ellipsis is similar to a full slice,
323306
# should preserve `freq` attribute
324307
freq = self.freq
308+
elif com.is_bool_indexer(key):
309+
new_key = lib.maybe_booleans_to_slice(key.view(np.uint8))
310+
if isinstance(new_key, slice):
311+
return self._get_getitem_freq(new_key)
325312
return freq
326313

327314
def __setitem__(

pandas/core/indexes/datetimelike.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,14 @@ def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs):
190190
indices = ensure_int64(indices)
191191

192192
maybe_slice = lib.maybe_indices_to_slice(indices, len(self))
193-
if isinstance(maybe_slice, slice):
194-
return self[maybe_slice]
195193

196-
return ExtensionIndex.take(
194+
result = ExtensionIndex.take(
197195
self, indices, axis, allow_fill, fill_value, **kwargs
198196
)
197+
if isinstance(maybe_slice, slice):
198+
freq = self._data._get_getitem_freq(maybe_slice)
199+
result._data._freq = freq
200+
return result
199201

200202
@doc(IndexOpsMixin.searchsorted, klass="Datetime-like Index")
201203
def searchsorted(self, value, side="left", sorter=None):

pandas/tests/series/indexing/test_boolean.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import numpy as np
22
import pytest
33

4-
from pandas import Index, Series
4+
from pandas import Index, Series, date_range
55
import pandas._testing as tm
66
from pandas.core.indexing import IndexingError
77

@@ -128,3 +128,19 @@ def test_get_set_boolean_different_order(string_series):
128128
sel = string_series[ordered > 0]
129129
exp = string_series[string_series > 0]
130130
tm.assert_series_equal(sel, exp)
131+
132+
133+
def test_getitem_boolean_dt64_copies():
134+
# GH#36210
135+
dti = date_range("2016-01-01", periods=4, tz="US/Pacific")
136+
key = np.array([True, True, False, False])
137+
138+
ser = Series(dti._data)
139+
140+
res = ser[key]
141+
assert res._values._data.base is None
142+
143+
# compare with numeric case for reference
144+
ser2 = Series(range(4))
145+
res2 = ser2[key]
146+
assert res2._values.base is None

0 commit comments

Comments
 (0)