Skip to content

Commit 41f66af

Browse files
phoflyehoshuadimarsky
authored andcommitted
BUG: boolean indexer with NA raising when reindex is necessary (pandas-dev#47623)
1 parent d64cb9b commit 41f66af

File tree

3 files changed

+30
-4
lines changed

3 files changed

+30
-4
lines changed

doc/source/whatsnew/v1.5.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,7 @@ Indexing
885885
- Bug when setting a value too large for a :class:`Series` dtype failing to coerce to a common type (:issue:`26049`, :issue:`32878`)
886886
- Bug in :meth:`loc.__setitem__` treating ``range`` keys as positional instead of label-based (:issue:`45479`)
887887
- Bug in :meth:`Series.__setitem__` when setting ``boolean`` dtype values containing ``NA`` incorrectly raising instead of casting to ``boolean`` dtype (:issue:`45462`)
888+
- Bug in :meth:`Series.loc` raising with boolean indexer containing ``NA`` when :class:`Index` did not match (:issue:`46551`)
888889
- Bug in :meth:`Series.__setitem__` where setting :attr:`NA` into a numeric-dtype :class:`Series` would incorrectly upcast to object-dtype rather than treating the value as ``np.nan`` (:issue:`44199`)
889890
- Bug in :meth:`DataFrame.loc` when setting values to a column and right hand side is a dictionary (:issue:`47216`)
890891
- Bug in :meth:`DataFrame.loc` when setting a :class:`DataFrame` not aligning index in some cases (:issue:`47578`)

pandas/core/indexing.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from pandas.core.dtypes.common import (
3131
is_array_like,
3232
is_bool_dtype,
33+
is_extension_array_dtype,
3334
is_hashable,
3435
is_integer,
3536
is_iterator,
@@ -2536,15 +2537,20 @@ def check_bool_indexer(index: Index, key) -> np.ndarray:
25362537
"""
25372538
result = key
25382539
if isinstance(key, ABCSeries) and not key.index.equals(index):
2539-
result = result.reindex(index)
2540-
mask = isna(result._values)
2541-
if mask.any():
2540+
indexer = result.index.get_indexer_for(index)
2541+
if -1 in indexer:
25422542
raise IndexingError(
25432543
"Unalignable boolean Series provided as "
25442544
"indexer (index of the boolean Series and of "
25452545
"the indexed object do not match)."
25462546
)
2547-
return result.astype(bool)._values
2547+
2548+
result = result.take(indexer)
2549+
2550+
# fall through for boolean
2551+
if not is_extension_array_dtype(result.dtype):
2552+
return result.astype(bool)._values
2553+
25482554
if is_object_dtype(key):
25492555
# key might be object-dtype bool, check_array_indexer needs bool array
25502556
result = np.asarray(result, dtype=bool)

pandas/tests/series/indexing/test_indexing.py

+19
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
import numpy as np
66
import pytest
77

8+
from pandas.errors import IndexingError
9+
810
from pandas import (
11+
NA,
912
DataFrame,
1013
IndexSlice,
1114
MultiIndex,
@@ -330,6 +333,22 @@ def test_loc_setitem_all_false_indexer():
330333
tm.assert_series_equal(ser, expected)
331334

332335

336+
def test_loc_boolean_indexer_non_matching_index():
337+
# GH#46551
338+
ser = Series([1])
339+
result = ser.loc[Series([NA, False], dtype="boolean")]
340+
expected = Series([], dtype="int64")
341+
tm.assert_series_equal(result, expected)
342+
343+
344+
def test_loc_boolean_indexer_miss_matching_index():
345+
# GH#46551
346+
ser = Series([1])
347+
indexer = Series([NA, False], dtype="boolean", index=[1, 2])
348+
with pytest.raises(IndexingError, match="Unalignable"):
349+
ser.loc[indexer]
350+
351+
333352
class TestDeprecatedIndexers:
334353
@pytest.mark.parametrize("key", [{1}, {1: 1}])
335354
def test_getitem_dict_and_set_deprecated(self, key):

0 commit comments

Comments
 (0)