Skip to content

Commit dbf2971

Browse files
committed
BUG: DatetimeIndex slicing with boolean Index raises TypeError
1 parent 7343fd3 commit dbf2971

File tree

8 files changed

+97
-3
lines changed

8 files changed

+97
-3
lines changed

doc/source/whatsnew/v0.24.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ Indexing
738738
- Bug in :meth:`DataFrame.loc` when indexing with an :class:`IntervalIndex` (:issue:`19977`)
739739
- :class:`Index` no longer mangles ``None``, ``NaN`` and ``NaT``, i.e. they are treated as three different keys. However, for numeric Index all three are still coerced to a ``NaN`` (:issue:`22332`)
740740
- Bug in `scalar in Index` if scalar is a float while the ``Index`` is of integer dtype (:issue:`22085`)
741+
- Bug in :class:`Index` slicing with boolean :class:`Index` may raise ``TypeError`` (:issue:`22533`)
741742

742743
Missing
743744
^^^^^^^

pandas/core/arrays/datetimelike.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ def __getitem__(self, key):
171171
return self._box_func(val)
172172

173173
if com.is_bool_indexer(key):
174-
key = np.asarray(key)
174+
key = np.asarray(key, dtype=bool)
175175
if key.all():
176176
key = slice(0, None, None)
177177
else:

pandas/core/indexes/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2070,7 +2070,7 @@ def __getitem__(self, key):
20702070
return promote(getitem(key))
20712071

20722072
if com.is_bool_indexer(key):
2073-
key = np.asarray(key)
2073+
key = np.asarray(key, dtype=bool)
20742074

20752075
key = com.values_from_object(key)
20762076
result = getitem(key)

pandas/core/indexes/multi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1607,7 +1607,7 @@ def __getitem__(self, key):
16071607
return tuple(retval)
16081608
else:
16091609
if com.is_bool_indexer(key):
1610-
key = np.asarray(key)
1610+
key = np.asarray(key, dtype=bool)
16111611
sortorder = self.sortorder
16121612
else:
16131613
# cannot be sure whether the result will be sorted

pandas/tests/indexes/datetimes/test_indexing.py

+22
Original file line numberDiff line numberDiff line change
@@ -600,3 +600,25 @@ def test_get_loc_nat(self):
600600
# GH#20464
601601
index = DatetimeIndex(['1/3/2000', 'NaT'])
602602
assert index.get_loc(pd.NaT) == 1
603+
604+
@pytest.mark.parametrize('ind1', [[True] * 5, pd.Index([True] * 5)])
605+
@pytest.mark.parametrize('ind2', [[True, False, True, False, False],
606+
pd.Index([True, False, True, False,
607+
False])])
608+
def test_getitem_bool_index_all(self, ind1, ind2):
609+
# GH#22533
610+
idx = pd.date_range('2011-01-01', '2011-01-05', freq='D', name='idx')
611+
tm.assert_index_equal(idx[ind1], idx)
612+
613+
expected = pd.DatetimeIndex(['2011-01-01', '2011-01-03'], name='idx')
614+
tm.assert_index_equal(idx[ind2], expected)
615+
616+
@pytest.mark.parametrize('ind1', [[True], pd.Index([True])])
617+
@pytest.mark.parametrize('ind2', [[False], pd.Index([False])])
618+
def test_getitem_bool_index_single(self, ind1, ind2):
619+
# GH#22533
620+
idx = pd.DatetimeIndex(['2011-01-01'], name='idx')
621+
tm.assert_index_equal(idx[ind1], idx)
622+
623+
expected = pd.DatetimeIndex([], name='idx')
624+
tm.assert_index_equal(idx[ind2], expected)

pandas/tests/indexes/multi/test_indexing.py

+27
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,33 @@ def test_get_indexer_consistency(idx):
224224
assert indexer.dtype == np.intp
225225

226226

227+
@pytest.mark.parametrize('ind1', [[True] * 5, pd.Index([True] * 5)])
228+
@pytest.mark.parametrize('ind2', [[True, False, True, False, False],
229+
pd.Index([True, False, True, False,
230+
False])])
231+
def test_getitem_bool_index_all(ind1, ind2):
232+
# GH#22533
233+
idx = MultiIndex.from_tuples([(10, 1), (20, 2), (30, 3),
234+
(40, 4), (50, 5)])
235+
tm.assert_index_equal(idx[ind1], idx)
236+
237+
expected = MultiIndex.from_tuples([(10, 1), (30, 3)])
238+
tm.assert_index_equal(idx[ind2], expected)
239+
240+
241+
@pytest.mark.parametrize('ind1', [[True], pd.Index([True])])
242+
@pytest.mark.parametrize('ind2', [[False], pd.Index([False])])
243+
def test_getitem_bool_index_single(ind1, ind2):
244+
# GH#22533
245+
idx = MultiIndex.from_tuples([(10, 1)])
246+
tm.assert_index_equal(idx[ind1], idx)
247+
248+
expected = pd.MultiIndex(levels=[np.array([], dtype=np.int64),
249+
np.array([], dtype=np.int64)],
250+
labels=[[], []])
251+
tm.assert_index_equal(idx[ind2], expected)
252+
253+
227254
def test_get_loc(idx):
228255
assert idx.get_loc(('foo', 'two')) == 1
229256
assert idx.get_loc(('baz', 'two')) == 3

pandas/tests/indexes/test_base.py

+22
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,28 @@ def test_getitem_error(self, indices, itm):
721721
with pytest.raises(IndexError):
722722
indices[itm]
723723

724+
@pytest.mark.parametrize('ind1', [[True] * 5, pd.Index([True] * 5)])
725+
@pytest.mark.parametrize('ind2', [[True, False, True, False, False],
726+
pd.Index([True, False, True, False,
727+
False])])
728+
def test_getitem_bool_index_all(self, ind1, ind2):
729+
# GH#22533
730+
idx = pd.Index(['a', 'b', 'c', 'd', 'e'], name='idx')
731+
tm.assert_index_equal(idx[ind1], idx)
732+
733+
expected = pd.Index(['a', 'c'], name='idx')
734+
tm.assert_index_equal(idx[ind2], expected)
735+
736+
@pytest.mark.parametrize('ind1', [[True], pd.Index([True])])
737+
@pytest.mark.parametrize('ind2', [[False], pd.Index([False])])
738+
def test_getitem_bool_index_single(self, ind1, ind2):
739+
# GH#22533
740+
idx = pd.Index(['a'], name='idx')
741+
tm.assert_index_equal(idx[ind1], idx)
742+
743+
expected = pd.Index([], name='idx')
744+
tm.assert_index_equal(idx[ind2], expected)
745+
724746
def test_intersection(self):
725747
first = self.strIndex[:20]
726748
second = self.strIndex[:10]

pandas/tests/indexes/test_numeric.py

+22
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,28 @@ def test_join_outer(self):
843843
tm.assert_numpy_array_equal(lidx, elidx)
844844
tm.assert_numpy_array_equal(ridx, eridx)
845845

846+
@pytest.mark.parametrize('ind1', [[True] * 5, pd.Index([True] * 5)])
847+
@pytest.mark.parametrize('ind2', [[True, False, True, False, False],
848+
pd.Index([True, False, True, False,
849+
False])])
850+
def test_getitem_bool_index_all(self, ind1, ind2):
851+
# GH#22533
852+
idx = pd.Int64Index([1, 2, 3, 4, 5], name='idx')
853+
tm.assert_index_equal(idx[ind1], idx)
854+
855+
expected = pd.Int64Index([1, 3], name='idx')
856+
tm.assert_index_equal(idx[ind2], expected)
857+
858+
@pytest.mark.parametrize('ind1', [[True], pd.Index([True])])
859+
@pytest.mark.parametrize('ind2', [[False], pd.Index([False])])
860+
def test_getitem_bool_index_single(self, ind1, ind2):
861+
# GH#22533
862+
idx = pd.Int64Index([1], name='idx')
863+
tm.assert_index_equal(idx[ind1], idx)
864+
865+
expected = pd.Int64Index([], name='idx')
866+
tm.assert_index_equal(idx[ind2], expected)
867+
846868

847869
class TestUInt64Index(NumericInt):
848870

0 commit comments

Comments
 (0)