Skip to content

Commit 1c8614d

Browse files
yuanx749SpoopyPillowmroeschke
authored
BUG: Assigning boolean series with boolean indexer (#61743)
* extra check when casting to boolean * full check for casting to boolean * specify bug * fixed comparison with 1 and 0 * return casted as bool * using lib is_bool to check for bool * made element iterable * ravel instead of flatten * more efficient check * added test case * format * Improve fix * Add test and note * Update pandas/core/dtypes/cast.py Co-authored-by: Matthew Roeschke <[email protected]> * Add test for np.nan --------- Co-authored-by: Michael Hu <[email protected]> Co-authored-by: Matthew Roeschke <[email protected]>
1 parent 7f783db commit 1c8614d

File tree

4 files changed

+34
-0
lines changed

4 files changed

+34
-0
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,7 @@ Indexing
752752
- Bug in :meth:`DataFrame.loc` with inconsistent behavior of loc-set with 2 given indexes to Series (:issue:`59933`)
753753
- Bug in :meth:`Index.get_indexer` and similar methods when ``NaN`` is located at or after position 128 (:issue:`58924`)
754754
- Bug in :meth:`MultiIndex.insert` when a new value inserted to a datetime-like level gets cast to ``NaT`` and fails indexing (:issue:`60388`)
755+
- Bug in :meth:`Series.__setitem__` when assigning boolean series with boolean indexer will raise ``LossySetitemError`` (:issue:`57338`)
755756
- Bug in printing :attr:`Index.names` and :attr:`MultiIndex.levels` would not escape single quotes (:issue:`60190`)
756757
- Bug in reindexing of :class:`DataFrame` with :class:`PeriodDtype` columns in case of consolidated block (:issue:`60980`, :issue:`60273`)
757758

pandas/core/dtypes/cast.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,6 +1926,10 @@ def np_can_hold_element(dtype: np.dtype, element: Any) -> Any:
19261926
# i.e. there are pd.NA elements
19271927
raise LossySetitemError
19281928
return element
1929+
# GH 57338 check boolean array set as object type
1930+
if tipo.kind == "O" and isinstance(element, np.ndarray):
1931+
if lib.is_bool_array(element):
1932+
return element.astype("bool")
19291933
raise LossySetitemError
19301934
if lib.is_bool(element):
19311935
return element

pandas/tests/dtypes/cast/test_can_hold_element.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,22 @@ def test_can_hold_element_int8_int():
7777
assert not can_hold_element(arr, np.uint32(element))
7878
assert not can_hold_element(arr, np.int64(element))
7979
assert not can_hold_element(arr, np.uint64(element))
80+
81+
82+
def test_can_hold_element_bool():
83+
arr = np.array([], dtype=bool)
84+
85+
element = True
86+
assert can_hold_element(arr, element)
87+
assert can_hold_element(arr, np.array([element]))
88+
assert can_hold_element(arr, np.array([element], dtype=object))
89+
90+
element = 1
91+
assert not can_hold_element(arr, element)
92+
assert not can_hold_element(arr, np.array([element]))
93+
assert not can_hold_element(arr, np.array([element], dtype=object))
94+
95+
element = np.nan
96+
assert not can_hold_element(arr, element)
97+
assert not can_hold_element(arr, np.array([element]))
98+
assert not can_hold_element(arr, np.array([element], dtype=object))

pandas/tests/series/indexing/test_setitem.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,3 +1838,13 @@ def test_setitem_empty_mask_dont_upcast_dt64():
18381838
ser.mask(mask, "foo", inplace=True)
18391839
assert ser.dtype == dti.dtype # no-op -> dont upcast
18401840
tm.assert_series_equal(ser, orig)
1841+
1842+
1843+
def test_setitem_bool_dtype_with_boolean_indexer():
1844+
# GH 57338
1845+
s1 = Series([True, True, True], dtype=bool)
1846+
s2 = Series([False, False, False], dtype=bool)
1847+
condition = [False, True, False]
1848+
s1[condition] = s2[condition]
1849+
expected = Series([True, False, True], dtype=bool)
1850+
tm.assert_series_equal(s1, expected)

0 commit comments

Comments
 (0)