Skip to content

Commit

Permalink
BUG: DatetimeIndex slicing with boolean Index raises TypeError (panda…
Browse files Browse the repository at this point in the history
  • Loading branch information
sinhrks authored and tm9k1 committed Nov 19, 2018
1 parent c53547a commit 1bbc5e9
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 8 deletions.
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v0.24.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,7 @@ Indexing
- Bug in `MultiIndex.set_levels` when levels value is not subscriptable (:issue:`23273`)
- Bug where setting a timedelta column by ``Index`` causes it to be casted to double, and therefore lose precision (:issue:`23511`)
- 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`)

- Bug in :class:`Index` slicing with boolean :class:`Index` may raise ``TypeError`` (:issue:`22533`)

Missing
^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def __getitem__(self, key):
return self._box_func(val)

if com.is_bool_indexer(key):
key = np.asarray(key)
key = np.asarray(key, dtype=bool)
if key.all():
key = slice(0, None, None)
else:
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2078,7 +2078,7 @@ def __getitem__(self, key):
return promote(getitem(key))

if com.is_bool_indexer(key):
key = np.asarray(key)
key = np.asarray(key, dtype=bool)

key = com.values_from_object(key)
result = getitem(key)
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/indexes/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -1614,7 +1614,7 @@ def __getitem__(self, key):
return tuple(retval)
else:
if com.is_bool_indexer(key):
key = np.asarray(key)
key = np.asarray(key, dtype=bool)
sortorder = self.sortorder
else:
# cannot be sure whether the result will be sorted
Expand Down
27 changes: 27 additions & 0 deletions pandas/tests/indexes/multi/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,33 @@ def test_get_indexer_consistency(idx):
assert indexer.dtype == np.intp


@pytest.mark.parametrize('ind1', [[True] * 5, pd.Index([True] * 5)])
@pytest.mark.parametrize('ind2', [[True, False, True, False, False],
pd.Index([True, False, True, False,
False])])
def test_getitem_bool_index_all(ind1, ind2):
# GH#22533
idx = MultiIndex.from_tuples([(10, 1), (20, 2), (30, 3),
(40, 4), (50, 5)])
tm.assert_index_equal(idx[ind1], idx)

expected = MultiIndex.from_tuples([(10, 1), (30, 3)])
tm.assert_index_equal(idx[ind2], expected)


@pytest.mark.parametrize('ind1', [[True], pd.Index([True])])
@pytest.mark.parametrize('ind2', [[False], pd.Index([False])])
def test_getitem_bool_index_single(ind1, ind2):
# GH#22533
idx = MultiIndex.from_tuples([(10, 1)])
tm.assert_index_equal(idx[ind1], idx)

expected = pd.MultiIndex(levels=[np.array([], dtype=np.int64),
np.array([], dtype=np.int64)],
labels=[[], []])
tm.assert_index_equal(idx[ind2], expected)


def test_get_loc(idx):
assert idx.get_loc(('foo', 'two')) == 1
assert idx.get_loc(('baz', 'two')) == 3
Expand Down
34 changes: 30 additions & 4 deletions pandas/tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,19 +178,20 @@ def setup_method(self, method):
self.unicode_index = tm.makeUnicodeIndex(10, name='a')

arr = np.random.randn(10)
self.bool_series = Series(arr, index=self.bool_index, name='a')
self.int_series = Series(arr, index=self.int_index, name='a')
self.float_series = Series(arr, index=self.float_index, name='a')
self.dt_series = Series(arr, index=self.dt_index, name='a')
self.dt_tz_series = self.dt_tz_index.to_series(keep_tz=True)
self.period_series = Series(arr, index=self.period_index, name='a')
self.string_series = Series(arr, index=self.string_index, name='a')
self.unicode_series = Series(arr, index=self.unicode_index, name='a')

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

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

def test_getitem(self):
for i in self.indexes:
s = pd.Series(i)

assert i[0] == s.iloc[0]
assert i[5] == s.iloc[5]
assert i[-1] == s.iloc[-1]

assert i[-1] == i[9]

pytest.raises(IndexError, i.__getitem__, 20)
pytest.raises(IndexError, s.iloc.__getitem__, 20)

@pytest.mark.parametrize('indexer_klass', [list, pd.Index])
@pytest.mark.parametrize('indexer', [[True] * 10, [False] * 10,
[True, False, True, True, False,
False, True, True, False, True]])
def test_bool_indexing(self, indexer_klass, indexer):
# GH 22533
for idx in self.indexes:
exp_idx = [i for i in range(len(indexer)) if indexer[i]]
tm.assert_index_equal(idx[indexer_klass(indexer)], idx[exp_idx])
s = pd.Series(idx)
tm.assert_series_equal(s[indexer_klass(indexer)], s.iloc[exp_idx])


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

0 comments on commit 1bbc5e9

Please sign in to comment.