Skip to content

Commit d1b898b

Browse files
Backport PR #48234 on branch 1.5.x (REGR: Fix regression RecursionError when replacing numeric scalar with None) (#49414)
Backport PR #48234: REGR: Fix regression RecursionError when replacing numeric scalar with None Co-authored-by: Patrick Hoefler <[email protected]>
1 parent 1396da4 commit d1b898b

File tree

4 files changed

+25
-3
lines changed

4 files changed

+25
-3
lines changed

doc/source/whatsnew/v1.5.2.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ including other versions of pandas.
1313

1414
Fixed regressions
1515
~~~~~~~~~~~~~~~~~
16-
-
16+
- Fixed regression in :meth:`Series.replace` raising ``RecursionError`` with numeric dtype and when specifying ``value=None`` (:issue:`45725`)
1717
-
1818

1919
.. ---------------------------------------------------------------------------

pandas/core/internals/blocks.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,6 @@ def replace(
569569
# Note: the checks we do in NDFrame.replace ensure we never get
570570
# here with listlike to_replace or value, as those cases
571571
# go through replace_list
572-
573572
values = self.values
574573

575574
if isinstance(values, Categorical):
@@ -608,7 +607,10 @@ def replace(
608607
return blocks
609608

610609
elif self.ndim == 1 or self.shape[0] == 1:
611-
blk = self.coerce_to_target_dtype(value)
610+
if value is None:
611+
blk = self.astype(np.dtype(object))
612+
else:
613+
blk = self.coerce_to_target_dtype(value)
612614
return blk.replace(
613615
to_replace=to_replace,
614616
value=value,

pandas/tests/frame/methods/test_replace.py

+12
Original file line numberDiff line numberDiff line change
@@ -1496,6 +1496,18 @@ def test_replace_list_with_mixed_type(
14961496
result = obj.replace(box(to_replace), value)
14971497
tm.assert_equal(result, expected)
14981498

1499+
@pytest.mark.parametrize("val", [2, np.nan, 2.0])
1500+
def test_replace_value_none_dtype_numeric(self, val):
1501+
# GH#48231
1502+
df = DataFrame({"a": [1, val]})
1503+
result = df.replace(val, None)
1504+
expected = DataFrame({"a": [1, None]}, dtype=object)
1505+
tm.assert_frame_equal(result, expected)
1506+
1507+
df = DataFrame({"a": [1, val]})
1508+
result = df.replace({val: None})
1509+
tm.assert_frame_equal(result, expected)
1510+
14991511

15001512
class TestDataFrameReplaceRegex:
15011513
@pytest.mark.parametrize(

pandas/tests/series/methods/test_replace.py

+8
Original file line numberDiff line numberDiff line change
@@ -667,3 +667,11 @@ def test_replace_different_int_types(self, any_int_numpy_dtype):
667667
result = labs.replace(map_dict)
668668
expected = labs.replace({0: 0, 2: 1, 1: 2})
669669
tm.assert_series_equal(result, expected)
670+
671+
@pytest.mark.parametrize("val", [2, np.nan, 2.0])
672+
def test_replace_value_none_dtype_numeric(self, val):
673+
# GH#48231
674+
ser = pd.Series([1, val])
675+
result = ser.replace(val, None)
676+
expected = pd.Series([1, None], dtype=object)
677+
tm.assert_series_equal(result, expected)

0 commit comments

Comments
 (0)