Skip to content

Fix issue #47101 #59492

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
18 changes: 16 additions & 2 deletions pandas/core/missing.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,25 @@ def mask_missing(arr: ArrayLike, values_to_mask) -> npt.NDArray[np.bool_]:
new_mask = np.zeros(arr.shape, dtype=np.bool_)
new_mask[arr_mask] = arr[arr_mask] == x
else:
new_mask = arr == x
# GH#47101
# Fix where type bool has no attribute to_numpy() by first
# attempting to broadcast with np.equal for some cases, and then
# an explicit type check when checking the mask for any straggling
# cases. Where a literal comparison would fail np.equal we fall back
# to the original equality check.
try:
# In case of an uncastable type, this will emit TypeError
new_mask = np.equal(arr, x) # type: ignore[arg-type]
except TypeError:
# Old behaviour for uncastable types
new_mask = arr == x

if not isinstance(new_mask, np.ndarray):
# usually BooleanArray
new_mask = new_mask.to_numpy(dtype=bool, na_value=False)
if isinstance(new_mask, bool):
new_mask = np.array([new_mask], dtype= bool)
else:
new_mask = new_mask.to_numpy(dtype=bool, na_value=False)
mask |= new_mask

if na_mask.any():
Expand Down
7 changes: 7 additions & 0 deletions pandas/tests/frame/methods/test_replace.py
Original file line number Diff line number Diff line change
Expand Up @@ -1518,3 +1518,10 @@ def test_replace_object_splitting(self, using_infer_string):
assert len(df._mgr.blocks) == 2
else:
assert len(df._mgr.blocks) == 1

def test_replace_bool_to_numpy_attributeerror(self):
# GH#47101
pass_pre_patch = DataFrame({"d":[None]})
tm.assert_frame_equal(pass_pre_patch, pass_pre_patch.replace("", pd.NA))
fail_pre_patch = DataFrame({"d":[pd.NA]})
tm.assert_frame_equal(fail_pre_patch, fail_pre_patch.replace("", pd.NA))