Skip to content

Commit

Permalink
Backport PR pandas-dev#56769 on branch 2.2.x (BUG: replace matching F…
Browse files Browse the repository at this point in the history
…loats with bools for ea dtypes) (pandas-dev#56780)

Backport PR pandas-dev#56769: BUG: replace matching Floats with bools for ea dtypes

Co-authored-by: Patrick Hoefler <61934744+phofl@users.noreply.github.com>
  • Loading branch information
meeseeksmachine and phofl authored Jan 8, 2024
1 parent 57079b6 commit 41f22b3
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 14 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,7 @@ Numeric
- Bug in :meth:`Series.__floordiv__` and :meth:`Series.__truediv__` for :class:`ArrowDtype` with integral dtypes raising for large divisors (:issue:`56706`)
- Bug in :meth:`Series.__floordiv__` for :class:`ArrowDtype` with integral dtypes raising for large values (:issue:`56645`)
- Bug in :meth:`Series.pow` not filling missing values correctly (:issue:`55512`)
- Bug in :meth:`Series.replace` and :meth:`DataFrame.replace` matching float ``0.0`` with ``False`` and vice versa (:issue:`55398`)

Conversion
^^^^^^^^^^
Expand Down
42 changes: 28 additions & 14 deletions pandas/core/missing.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from pandas.core.dtypes.cast import infer_dtype_from
from pandas.core.dtypes.common import (
is_array_like,
is_bool_dtype,
is_numeric_dtype,
is_numeric_v_string_like,
is_object_dtype,
Expand Down Expand Up @@ -100,21 +101,34 @@ def mask_missing(arr: ArrayLike, values_to_mask) -> npt.NDArray[np.bool_]:

# GH 21977
mask = np.zeros(arr.shape, dtype=bool)
for x in nonna:
if is_numeric_v_string_like(arr, x):
# GH#29553 prevent numpy deprecation warnings
pass
else:
if potential_na:
new_mask = np.zeros(arr.shape, dtype=np.bool_)
new_mask[arr_mask] = arr[arr_mask] == x
if (
is_numeric_dtype(arr.dtype)
and not is_bool_dtype(arr.dtype)
and is_bool_dtype(nonna.dtype)
):
pass
elif (
is_bool_dtype(arr.dtype)
and is_numeric_dtype(nonna.dtype)
and not is_bool_dtype(nonna.dtype)
):
pass
else:
for x in nonna:
if is_numeric_v_string_like(arr, x):
# GH#29553 prevent numpy deprecation warnings
pass
else:
new_mask = arr == x

if not isinstance(new_mask, np.ndarray):
# usually BooleanArray
new_mask = new_mask.to_numpy(dtype=bool, na_value=False)
mask |= new_mask
if potential_na:
new_mask = np.zeros(arr.shape, dtype=np.bool_)
new_mask[arr_mask] = arr[arr_mask] == x
else:
new_mask = arr == x

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

if na_mask.any():
mask |= isna(arr)
Expand Down
12 changes: 12 additions & 0 deletions pandas/tests/series/methods/test_replace.py
Original file line number Diff line number Diff line change
Expand Up @@ -799,3 +799,15 @@ def test_replace_numeric_column_with_na(self, val):

ser.replace(to_replace=1, value=pd.NA, inplace=True)
tm.assert_series_equal(ser, expected)

def test_replace_ea_float_with_bool(self):
# GH#55398
ser = pd.Series([0.0], dtype="Float64")
expected = ser.copy()
result = ser.replace(False, 1.0)
tm.assert_series_equal(result, expected)

ser = pd.Series([False], dtype="boolean")
expected = ser.copy()
result = ser.replace(0.0, True)
tm.assert_series_equal(result, expected)

0 comments on commit 41f22b3

Please sign in to comment.