Skip to content

Commit

Permalink
BUG: DatetimeIndex slicing with boolean Index raises TypeError
Browse files Browse the repository at this point in the history
  • Loading branch information
sinhrks committed Sep 28, 2018
1 parent 7343fd3 commit dbf2971
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 3 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.24.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,7 @@ Indexing
- Bug in :meth:`DataFrame.loc` when indexing with an :class:`IntervalIndex` (:issue:`19977`)
- :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`)
- Bug in `scalar in Index` if scalar is a float while the ``Index`` is of integer dtype (:issue:`22085`)
- 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 @@ -171,7 +171,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 @@ -2070,7 +2070,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 @@ -1607,7 +1607,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
22 changes: 22 additions & 0 deletions pandas/tests/indexes/datetimes/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,3 +600,25 @@ def test_get_loc_nat(self):
# GH#20464
index = DatetimeIndex(['1/3/2000', 'NaT'])
assert index.get_loc(pd.NaT) == 1

@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(self, ind1, ind2):
# GH#22533
idx = pd.date_range('2011-01-01', '2011-01-05', freq='D', name='idx')
tm.assert_index_equal(idx[ind1], idx)

expected = pd.DatetimeIndex(['2011-01-01', '2011-01-03'], name='idx')
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(self, ind1, ind2):
# GH#22533
idx = pd.DatetimeIndex(['2011-01-01'], name='idx')
tm.assert_index_equal(idx[ind1], idx)

expected = pd.DatetimeIndex([], name='idx')
tm.assert_index_equal(idx[ind2], expected)
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 @@ -224,6 +224,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
22 changes: 22 additions & 0 deletions pandas/tests/indexes/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,28 @@ def test_getitem_error(self, indices, itm):
with pytest.raises(IndexError):
indices[itm]

@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(self, ind1, ind2):
# GH#22533
idx = pd.Index(['a', 'b', 'c', 'd', 'e'], name='idx')
tm.assert_index_equal(idx[ind1], idx)

expected = pd.Index(['a', 'c'], name='idx')
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(self, ind1, ind2):
# GH#22533
idx = pd.Index(['a'], name='idx')
tm.assert_index_equal(idx[ind1], idx)

expected = pd.Index([], name='idx')
tm.assert_index_equal(idx[ind2], expected)

def test_intersection(self):
first = self.strIndex[:20]
second = self.strIndex[:10]
Expand Down
22 changes: 22 additions & 0 deletions pandas/tests/indexes/test_numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,28 @@ def test_join_outer(self):
tm.assert_numpy_array_equal(lidx, elidx)
tm.assert_numpy_array_equal(ridx, eridx)

@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(self, ind1, ind2):
# GH#22533
idx = pd.Int64Index([1, 2, 3, 4, 5], name='idx')
tm.assert_index_equal(idx[ind1], idx)

expected = pd.Int64Index([1, 3], name='idx')
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(self, ind1, ind2):
# GH#22533
idx = pd.Int64Index([1], name='idx')
tm.assert_index_equal(idx[ind1], idx)

expected = pd.Int64Index([], name='idx')
tm.assert_index_equal(idx[ind2], expected)


class TestUInt64Index(NumericInt):

Expand Down

0 comments on commit dbf2971

Please sign in to comment.