Skip to content

Commit 1e23524

Browse files
sinhrksjreback
authored andcommitted
BUG: DatetimeIndex slicing with boolean Index raises TypeError (#22852)
1 parent 691cb86 commit 1e23524

File tree

6 files changed

+61
-8
lines changed

6 files changed

+61
-8
lines changed

doc/source/whatsnew/v0.24.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,7 @@ Indexing
12221222
- Bug in `MultiIndex.set_levels` when levels value is not subscriptable (:issue:`23273`)
12231223
- Bug where setting a timedelta column by ``Index`` causes it to be casted to double, and therefore lose precision (:issue:`23511`)
12241224
- Bug in :func:`Index.union` and :func:`Index.intersection` where name of the ``Index`` of the result was not computed correctly for certain cases (:issue:`9943`, :issue:`9862`)
1225-
1225+
- Bug in :class:`Index` slicing with boolean :class:`Index` may raise ``TypeError`` (:issue:`22533`)
12261226

12271227
Missing
12281228
^^^^^^^

pandas/core/arrays/datetimelike.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def __getitem__(self, key):
161161
return self._box_func(val)
162162

163163
if com.is_bool_indexer(key):
164-
key = np.asarray(key)
164+
key = np.asarray(key, dtype=bool)
165165
if key.all():
166166
key = slice(0, None, None)
167167
else:

pandas/core/indexes/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2078,7 +2078,7 @@ def __getitem__(self, key):
20782078
return promote(getitem(key))
20792079

20802080
if com.is_bool_indexer(key):
2081-
key = np.asarray(key)
2081+
key = np.asarray(key, dtype=bool)
20822082

20832083
key = com.values_from_object(key)
20842084
result = getitem(key)

pandas/core/indexes/multi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,7 @@ def __getitem__(self, key):
16141614
return tuple(retval)
16151615
else:
16161616
if com.is_bool_indexer(key):
1617-
key = np.asarray(key)
1617+
key = np.asarray(key, dtype=bool)
16181618
sortorder = self.sortorder
16191619
else:
16201620
# cannot be sure whether the result will be sorted

pandas/tests/indexes/multi/test_indexing.py

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

228228

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

pandas/tests/test_base.py

+30-4
Original file line numberDiff line numberDiff line change
@@ -178,19 +178,20 @@ def setup_method(self, method):
178178
self.unicode_index = tm.makeUnicodeIndex(10, name='a')
179179

180180
arr = np.random.randn(10)
181+
self.bool_series = Series(arr, index=self.bool_index, name='a')
181182
self.int_series = Series(arr, index=self.int_index, name='a')
182183
self.float_series = Series(arr, index=self.float_index, name='a')
183184
self.dt_series = Series(arr, index=self.dt_index, name='a')
184185
self.dt_tz_series = self.dt_tz_index.to_series(keep_tz=True)
185186
self.period_series = Series(arr, index=self.period_index, name='a')
186187
self.string_series = Series(arr, index=self.string_index, name='a')
188+
self.unicode_series = Series(arr, index=self.unicode_index, name='a')
187189

188190
types = ['bool', 'int', 'float', 'dt', 'dt_tz', 'period', 'string',
189191
'unicode']
190-
fmts = ["{0}_{1}".format(t, f)
191-
for t in types for f in ['index', 'series']]
192-
self.objs = [getattr(self, f)
193-
for f in fmts if getattr(self, f, None) is not None]
192+
self.indexes = [getattr(self, '{}_index'.format(t)) for t in types]
193+
self.series = [getattr(self, '{}_series'.format(t)) for t in types]
194+
self.objs = self.indexes + self.series
194195

195196
def check_ops_properties(self, props, filter=None, ignore_failures=False):
196197
for op in props:
@@ -997,6 +998,31 @@ def test_validate_bool_args(self):
997998
with pytest.raises(ValueError):
998999
self.int_series.drop_duplicates(inplace=value)
9991000

1001+
def test_getitem(self):
1002+
for i in self.indexes:
1003+
s = pd.Series(i)
1004+
1005+
assert i[0] == s.iloc[0]
1006+
assert i[5] == s.iloc[5]
1007+
assert i[-1] == s.iloc[-1]
1008+
1009+
assert i[-1] == i[9]
1010+
1011+
pytest.raises(IndexError, i.__getitem__, 20)
1012+
pytest.raises(IndexError, s.iloc.__getitem__, 20)
1013+
1014+
@pytest.mark.parametrize('indexer_klass', [list, pd.Index])
1015+
@pytest.mark.parametrize('indexer', [[True] * 10, [False] * 10,
1016+
[True, False, True, True, False,
1017+
False, True, True, False, True]])
1018+
def test_bool_indexing(self, indexer_klass, indexer):
1019+
# GH 22533
1020+
for idx in self.indexes:
1021+
exp_idx = [i for i in range(len(indexer)) if indexer[i]]
1022+
tm.assert_index_equal(idx[indexer_klass(indexer)], idx[exp_idx])
1023+
s = pd.Series(idx)
1024+
tm.assert_series_equal(s[indexer_klass(indexer)], s.iloc[exp_idx])
1025+
10001026

10011027
class TestTranspose(Ops):
10021028
errmsg = "the 'axes' parameter is not supported"

0 commit comments

Comments
 (0)