Skip to content

Commit 0997ade

Browse files
committed
ERR: get_indexer returns the correct indexer when Index is numeric and target is boolean (#16877)
1 parent e0743a1 commit 0997ade

File tree

4 files changed

+19
-2
lines changed

4 files changed

+19
-2
lines changed

doc/source/whatsnew/v0.21.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ Other API Changes
481481
- :class:`Period` is now immutable, and will now raise an ``AttributeError`` when a user tries to assign a new value to the ``ordinal`` or ``freq`` attributes (:issue:`17116`).
482482
- :func:`to_datetime` when passed a tz-aware ``origin=`` kwarg will now raise a more informative ``ValueError`` rather than a ``TypeError`` (:issue:`16842`)
483483
- Renamed non-functional ``index`` to ``index_col`` in :func:`read_stata` to improve API consistency (:issue:`16342`)
484-
484+
- Bug in :func:`DataFrame.drop` caused boolean labels ``False`` and ``True`` to be treated as labels 0 and 1 respectively when dropping indices from a numeric index. This will now raise a ValueError (:issue:`16877`)
485485

486486
.. _whatsnew_0210.deprecations:
487487

pandas/core/indexes/base.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -2609,6 +2609,12 @@ def get_indexer(self, target, method=None, limit=None, tolerance=None):
26092609
if tolerance is not None:
26102610
tolerance = self._convert_tolerance(tolerance)
26112611

2612+
# Treat boolean labels passed to a numeric index as not found. Without
2613+
# this fix False and True would be treated as 0 and 1 respectively.
2614+
# (GH #16877)
2615+
if target.is_boolean() and self.is_numeric():
2616+
return np.repeat(-1, target.size)
2617+
26122618
pself, ptarget = self._maybe_promote(target)
26132619
if pself is not self or ptarget is not target:
26142620
return pself.get_indexer(ptarget, method=method, limit=limit,
@@ -2637,7 +2643,6 @@ def get_indexer(self, target, method=None, limit=None, tolerance=None):
26372643
'backfill or nearest reindexing')
26382644

26392645
indexer = self._engine.get_indexer(target._values)
2640-
26412646
return _ensure_platform_int(indexer)
26422647

26432648
def _convert_tolerance(self, tolerance):

pandas/tests/indexes/test_base.py

+7
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,13 @@ def test_get_indexer_strings(self):
11411141
with pytest.raises(TypeError):
11421142
idx.get_indexer(['a', 'b', 'c', 'd'], method='pad', tolerance=2)
11431143

1144+
def test_get_indexer_numeric_index_boolean_target(self):
1145+
# GH 16877
1146+
numeric_idx = pd.Index(range(4))
1147+
result = numeric_idx.get_indexer([True, False, True])
1148+
expected = np.array([-1, -1, -1], dtype=np.intp)
1149+
tm.assert_numpy_array_equal(result, expected)
1150+
11441151
def test_get_loc(self):
11451152
idx = pd.Index([0, 1, 2])
11461153
all_methods = [None, 'pad', 'backfill', 'nearest']

pandas/tests/series/test_indexing.py

+5
Original file line numberDiff line numberDiff line change
@@ -1783,6 +1783,11 @@ def test_drop(self):
17831783
expected = Series([3], index=[False])
17841784
assert_series_equal(result, expected)
17851785

1786+
# GH 16877
1787+
s = Series([2, 3], index=[0, 1])
1788+
with tm.assert_raises_regex(ValueError, 'not contained in axis'):
1789+
s.drop([False, True])
1790+
17861791
def test_align(self):
17871792
def _check_align(a, b, how='left', fill=None):
17881793
aa, ab = a.align(b, join=how, fill_value=fill)

0 commit comments

Comments
 (0)