Skip to content

Commit b4e2de4

Browse files
fixes
1 parent 7ae1a5e commit b4e2de4

File tree

2 files changed

+25
-22
lines changed

2 files changed

+25
-22
lines changed

pandas/core/internals/blocks.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,7 @@ def replace(
929929
blocks = blk.convert(
930930
copy=False,
931931
using_cow=using_cow,
932-
convert_string=convert_string or self.dtype != _dtype_obj,
932+
convert_string=convert_string or self.dtype == "string",
933933
)
934934
if len(blocks) > 1 or blocks[0].dtype != blk.dtype:
935935
warnings.warn(
@@ -987,7 +987,7 @@ def _replace_regex(
987987
inplace: bool = False,
988988
mask=None,
989989
using_cow: bool = False,
990-
convert_string: bool = True,
990+
convert_string=None,
991991
already_warned=None,
992992
) -> list[Block]:
993993
"""
@@ -1048,10 +1048,18 @@ def _replace_regex(
10481048
already_warned.warned_already = True
10491049

10501050
nbs = block.convert(
1051-
copy=False, using_cow=using_cow, convert_string=convert_string
1051+
copy=False,
1052+
using_cow=using_cow,
1053+
convert_string=convert_string or self.dtype == "string",
10521054
)
10531055
opt = get_option("future.no_silent_downcasting")
1054-
if (len(nbs) > 1 or nbs[0].dtype != block.dtype) and not opt:
1056+
if (
1057+
len(nbs) > 1
1058+
or (
1059+
nbs[0].dtype != block.dtype
1060+
and not (self.dtype == "string" and nbs[0].dtype == "string")
1061+
)
1062+
) and not opt:
10551063
warnings.warn(
10561064
# GH#54710
10571065
"Downcasting behavior in `replace` is deprecated and "
@@ -1088,7 +1096,7 @@ def replace_list(
10881096
values._replace(to_replace=src_list, value=dest_list, inplace=True)
10891097
return [blk]
10901098

1091-
convert_string = self.dtype != _dtype_obj
1099+
convert_string = self.dtype == "string"
10921100

10931101
# Exclude anything that we know we won't contain
10941102
pairs = [

pandas/tests/frame/methods/test_replace.py

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ def test_regex_replace_dict_nested_gh4115(self):
299299

300300
tm.assert_frame_equal(result, expected)
301301

302-
def test_regex_replace_list_to_scalar(self, mix_abc):
302+
def test_regex_replace_list_to_scalar(self, mix_abc, using_infer_string):
303303
df = DataFrame(mix_abc)
304304
expec = DataFrame(
305305
{
@@ -308,17 +308,20 @@ def test_regex_replace_list_to_scalar(self, mix_abc):
308308
"c": [np.nan, np.nan, np.nan, "d"],
309309
}
310310
)
311+
if using_infer_string:
312+
expec["b"] = expec["b"].astype("str")
311313
msg = "Downcasting behavior in `replace`"
312-
with tm.assert_produces_warning(FutureWarning, match=msg):
314+
warn = None if using_infer_string else FutureWarning
315+
with tm.assert_produces_warning(warn, match=msg):
313316
res = df.replace([r"\s*\.\s*", "a|b"], np.nan, regex=True)
314317
res2 = df.copy()
315318
res3 = df.copy()
316-
with tm.assert_produces_warning(FutureWarning, match=msg):
319+
with tm.assert_produces_warning(warn, match=msg):
317320
return_value = res2.replace(
318321
[r"\s*\.\s*", "a|b"], np.nan, regex=True, inplace=True
319322
)
320323
assert return_value is None
321-
with tm.assert_produces_warning(FutureWarning, match=msg):
324+
with tm.assert_produces_warning(warn, match=msg):
322325
return_value = res3.replace(
323326
regex=[r"\s*\.\s*", "a|b"], value=np.nan, inplace=True
324327
)
@@ -338,8 +341,6 @@ def test_regex_replace_str_to_numeric(self, mix_abc):
338341
return_value = res3.replace(regex=r"\s*\.\s*", value=0, inplace=True)
339342
assert return_value is None
340343
expec = DataFrame({"a": mix_abc["a"], "b": ["a", "b", 0, 0], "c": mix_abc["c"]})
341-
# TODO(infer_string)
342-
expec["c"] = expec["c"].astype(object)
343344
tm.assert_frame_equal(res, expec)
344345
tm.assert_frame_equal(res2, expec)
345346
tm.assert_frame_equal(res3, expec)
@@ -626,11 +627,7 @@ def test_replace_mixed2(self, using_infer_string):
626627
"B": Series([0, "foo"], dtype="object"),
627628
}
628629
)
629-
if using_infer_string:
630-
with tm.assert_produces_warning(FutureWarning, match="Downcasting"):
631-
result = df.replace([1, 2], ["foo", "bar"])
632-
else:
633-
result = df.replace([1, 2], ["foo", "bar"])
630+
result = df.replace([1, 2], ["foo", "bar"])
634631
tm.assert_frame_equal(result, expected)
635632

636633
def test_replace_mixed3(self):
@@ -1513,13 +1510,11 @@ def test_replace_with_compiled_regex(self):
15131510
expected = DataFrame(["z", "b", "c"])
15141511
tm.assert_frame_equal(result, expected)
15151512

1516-
def test_replace_intervals(self, using_infer_string):
1513+
def test_replace_intervals(self):
15171514
# https://github.com/pandas-dev/pandas/issues/35931
15181515
df = DataFrame({"a": [pd.Interval(0, 1), pd.Interval(0, 1)]})
1519-
warning = FutureWarning if using_infer_string else None
1520-
with tm.assert_produces_warning(warning, match="Downcasting"):
1521-
result = df.replace({"a": {pd.Interval(0, 1): "x"}})
1522-
expected = DataFrame({"a": ["x", "x"]})
1516+
result = df.replace({"a": {pd.Interval(0, 1): "x"}})
1517+
expected = DataFrame({"a": ["x", "x"]}, dtype=object)
15231518
tm.assert_frame_equal(result, expected)
15241519

15251520
def test_replace_unicode(self):
@@ -1620,7 +1615,7 @@ def test_regex_replace_scalar(
16201615
tm.assert_frame_equal(result, expected)
16211616

16221617
@pytest.mark.parametrize("regex", [False, True])
1623-
def test_replace_regex_dtype_frame(self, regex):
1618+
def test_replace_regex_dtype_frame(self, regex, using_infer_string):
16241619
# GH-48644
16251620
df1 = DataFrame({"A": ["0"], "B": ["0"]})
16261621
expected_df1 = DataFrame({"A": [1], "B": [1]})

0 commit comments

Comments
 (0)