66import numpy as np
77import pytest
88
9- from pandas ._config import using_string_dtype
10-
119import pandas as pd
1210from pandas import (
1311 DataFrame ,
@@ -30,7 +28,6 @@ def mix_abc() -> dict[str, list[float | str]]:
3028
3129
3230class TestDataFrameReplace :
33- @pytest .mark .xfail (using_string_dtype (), reason = "can't set float into string" )
3431 def test_replace_inplace (self , datetime_frame , float_string_frame ):
3532 datetime_frame .loc [datetime_frame .index [:5 ], "A" ] = np .nan
3633 datetime_frame .loc [datetime_frame .index [- 5 :], "A" ] = np .nan
@@ -46,7 +43,9 @@ def test_replace_inplace(self, datetime_frame, float_string_frame):
4643 mf .iloc [- 10 :, mf .columns .get_loc ("A" )] = np .nan
4744
4845 result = float_string_frame .replace (np .nan , 0 )
49- expected = float_string_frame .fillna (value = 0 )
46+ expected = float_string_frame .copy ()
47+ expected ["foo" ] = expected ["foo" ].astype (object )
48+ expected = expected .fillna (value = 0 )
5049 tm .assert_frame_equal (result , expected )
5150
5251 tsframe = datetime_frame .copy ()
@@ -290,34 +289,39 @@ def test_regex_replace_dict_nested_non_first_character(self, any_string_dtype):
290289 tm .assert_frame_equal (result , expected )
291290
292291 def test_regex_replace_dict_nested_gh4115 (self ):
293- df = DataFrame ({"Type" : ["Q" , "T" , "Q" , "Q" , "T" ], "tmp" : 2 })
292+ df = DataFrame (
293+ {"Type" : Series (["Q" , "T" , "Q" , "Q" , "T" ], dtype = object ), "tmp" : 2 }
294+ )
294295 expected = DataFrame ({"Type" : [0 , 1 , 0 , 0 , 1 ], "tmp" : 2 })
295296 msg = "Downcasting behavior in `replace`"
296297 with tm .assert_produces_warning (FutureWarning , match = msg ):
297298 result = df .replace ({"Type" : {"Q" : 0 , "T" : 1 }})
299+
298300 tm .assert_frame_equal (result , expected )
299301
300- @pytest .mark .xfail (using_string_dtype (), reason = "can't set float into string" )
301- def test_regex_replace_list_to_scalar (self , mix_abc ):
302+ def test_regex_replace_list_to_scalar (self , mix_abc , using_infer_string ):
302303 df = DataFrame (mix_abc )
303304 expec = DataFrame (
304305 {
305306 "a" : mix_abc ["a" ],
306- "b" : np . array ( [np .nan ] * 4 ) ,
307+ "b" : [np .nan ] * 4 ,
307308 "c" : [np .nan , np .nan , np .nan , "d" ],
308309 }
309310 )
311+ if using_infer_string :
312+ expec ["b" ] = expec ["b" ].astype ("str" )
310313 msg = "Downcasting behavior in `replace`"
311- 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 ):
312316 res = df .replace ([r"\s*\.\s*" , "a|b" ], np .nan , regex = True )
313317 res2 = df .copy ()
314318 res3 = df .copy ()
315- with tm .assert_produces_warning (FutureWarning , match = msg ):
319+ with tm .assert_produces_warning (warn , match = msg ):
316320 return_value = res2 .replace (
317321 [r"\s*\.\s*" , "a|b" ], np .nan , regex = True , inplace = True
318322 )
319323 assert return_value is None
320- with tm .assert_produces_warning (FutureWarning , match = msg ):
324+ with tm .assert_produces_warning (warn , match = msg ):
321325 return_value = res3 .replace (
322326 regex = [r"\s*\.\s*" , "a|b" ], value = np .nan , inplace = True
323327 )
@@ -326,7 +330,6 @@ def test_regex_replace_list_to_scalar(self, mix_abc):
326330 tm .assert_frame_equal (res2 , expec )
327331 tm .assert_frame_equal (res3 , expec )
328332
329- @pytest .mark .xfail (using_string_dtype (), reason = "can't set float into string" )
330333 def test_regex_replace_str_to_numeric (self , mix_abc ):
331334 # what happens when you try to replace a numeric value with a regex?
332335 df = DataFrame (mix_abc )
@@ -342,7 +345,6 @@ def test_regex_replace_str_to_numeric(self, mix_abc):
342345 tm .assert_frame_equal (res2 , expec )
343346 tm .assert_frame_equal (res3 , expec )
344347
345- @pytest .mark .xfail (using_string_dtype (), reason = "can't set float into string" )
346348 def test_regex_replace_regex_list_to_numeric (self , mix_abc ):
347349 df = DataFrame (mix_abc )
348350 res = df .replace ([r"\s*\.\s*" , "b" ], 0 , regex = True )
@@ -539,21 +541,28 @@ def test_replace_convert(self):
539541 res = rep .dtypes
540542 tm .assert_series_equal (expec , res )
541543
542- @pytest .mark .xfail (using_string_dtype (), reason = "can't set float into string" )
543544 def test_replace_mixed (self , float_string_frame ):
544545 mf = float_string_frame
545546 mf .iloc [5 :20 , mf .columns .get_loc ("foo" )] = np .nan
546547 mf .iloc [- 10 :, mf .columns .get_loc ("A" )] = np .nan
547548
548549 result = float_string_frame .replace (np .nan , - 18 )
549- expected = float_string_frame .fillna (value = - 18 )
550+ expected = float_string_frame .copy ()
551+ expected ["foo" ] = expected ["foo" ].astype (object )
552+ expected = expected .fillna (value = - 18 )
550553 tm .assert_frame_equal (result , expected )
551- tm .assert_frame_equal (result .replace (- 18 , np .nan ), float_string_frame )
554+ expected2 = float_string_frame .copy ()
555+ expected2 ["foo" ] = expected2 ["foo" ].astype (object )
556+ tm .assert_frame_equal (result .replace (- 18 , np .nan ), expected2 )
552557
553558 result = float_string_frame .replace (np .nan , - 1e8 )
554- expected = float_string_frame .fillna (value = - 1e8 )
559+ expected = float_string_frame .copy ()
560+ expected ["foo" ] = expected ["foo" ].astype (object )
561+ expected = expected .fillna (value = - 1e8 )
555562 tm .assert_frame_equal (result , expected )
556- tm .assert_frame_equal (result .replace (- 1e8 , np .nan ), float_string_frame )
563+ expected2 = float_string_frame .copy ()
564+ expected2 ["foo" ] = expected2 ["foo" ].astype (object )
565+ tm .assert_frame_equal (result .replace (- 1e8 , np .nan ), expected2 )
557566
558567 def test_replace_mixed_int_block_upcasting (self ):
559568 # int block upcasting
@@ -614,15 +623,11 @@ def test_replace_mixed2(self, using_infer_string):
614623
615624 expected = DataFrame (
616625 {
617- "A" : Series (["foo" , "bar" ]),
626+ "A" : Series (["foo" , "bar" ], dtype = "object" ),
618627 "B" : Series ([0 , "foo" ], dtype = "object" ),
619628 }
620629 )
621- if using_infer_string :
622- with tm .assert_produces_warning (FutureWarning , match = "Downcasting" ):
623- result = df .replace ([1 , 2 ], ["foo" , "bar" ])
624- else :
625- result = df .replace ([1 , 2 ], ["foo" , "bar" ])
630+ result = df .replace ([1 , 2 ], ["foo" , "bar" ])
626631 tm .assert_frame_equal (result , expected )
627632
628633 def test_replace_mixed3 (self ):
@@ -931,15 +936,16 @@ def test_replace_limit(self):
931936 # TODO
932937 pass
933938
934- def test_replace_dict_no_regex (self ):
939+ def test_replace_dict_no_regex (self , any_string_dtype ):
935940 answer = Series (
936941 {
937942 0 : "Strongly Agree" ,
938943 1 : "Agree" ,
939944 2 : "Neutral" ,
940945 3 : "Disagree" ,
941946 4 : "Strongly Disagree" ,
942- }
947+ },
948+ dtype = any_string_dtype ,
943949 )
944950 weights = {
945951 "Agree" : 4 ,
@@ -954,15 +960,16 @@ def test_replace_dict_no_regex(self):
954960 result = answer .replace (weights )
955961 tm .assert_series_equal (result , expected )
956962
957- def test_replace_series_no_regex (self ):
963+ def test_replace_series_no_regex (self , any_string_dtype ):
958964 answer = Series (
959965 {
960966 0 : "Strongly Agree" ,
961967 1 : "Agree" ,
962968 2 : "Neutral" ,
963969 3 : "Disagree" ,
964970 4 : "Strongly Disagree" ,
965- }
971+ },
972+ dtype = any_string_dtype ,
966973 )
967974 weights = Series (
968975 {
@@ -1060,16 +1067,15 @@ def test_nested_dict_overlapping_keys_replace_str(self):
10601067 expected = df .replace ({"a" : dict (zip (astr , bstr ))})
10611068 tm .assert_frame_equal (result , expected )
10621069
1063- @pytest .mark .xfail (using_string_dtype (), reason = "can't set float into string" )
1064- def test_replace_swapping_bug (self , using_infer_string ):
1070+ def test_replace_swapping_bug (self ):
10651071 df = DataFrame ({"a" : [True , False , True ]})
10661072 res = df .replace ({"a" : {True : "Y" , False : "N" }})
1067- expect = DataFrame ({"a" : ["Y" , "N" , "Y" ]})
1073+ expect = DataFrame ({"a" : ["Y" , "N" , "Y" ]}, dtype = object )
10681074 tm .assert_frame_equal (res , expect )
10691075
10701076 df = DataFrame ({"a" : [0 , 1 , 0 ]})
10711077 res = df .replace ({"a" : {0 : "Y" , 1 : "N" }})
1072- expect = DataFrame ({"a" : ["Y" , "N" , "Y" ]})
1078+ expect = DataFrame ({"a" : ["Y" , "N" , "Y" ]}, dtype = object )
10731079 tm .assert_frame_equal (res , expect )
10741080
10751081 def test_replace_period (self ):
@@ -1345,7 +1351,7 @@ def test_replace_commutative(self, df, to_replace, exp):
13451351 )
13461352 def test_replace_replacer_dtype (self , replacer ):
13471353 # GH26632
1348- df = DataFrame (["a" ])
1354+ df = DataFrame (["a" ], dtype = object )
13491355 msg = "Downcasting behavior in `replace` "
13501356 with tm .assert_produces_warning (FutureWarning , match = msg ):
13511357 result = df .replace ({"a" : replacer , "b" : replacer })
@@ -1462,6 +1468,7 @@ def test_replace_value_category_type(self):
14621468 input_df = input_df .replace ("obj1" , "obj9" )
14631469 result = input_df .replace ("cat2" , "catX" )
14641470
1471+ result = result .astype ({"col1" : "int64" , "col3" : "float64" , "col5" : "str" })
14651472 tm .assert_frame_equal (result , expected )
14661473
14671474 def test_replace_dict_category_type (self ):
@@ -1503,13 +1510,11 @@ def test_replace_with_compiled_regex(self):
15031510 expected = DataFrame (["z" , "b" , "c" ])
15041511 tm .assert_frame_equal (result , expected )
15051512
1506- def test_replace_intervals (self , using_infer_string ):
1513+ def test_replace_intervals (self ):
15071514 # https://github.com/pandas-dev/pandas/issues/35931
15081515 df = DataFrame ({"a" : [pd .Interval (0 , 1 ), pd .Interval (0 , 1 )]})
1509- warning = FutureWarning if using_infer_string else None
1510- with tm .assert_produces_warning (warning , match = "Downcasting" ):
1511- result = df .replace ({"a" : {pd .Interval (0 , 1 ): "x" }})
1512- expected = DataFrame ({"a" : ["x" , "x" ]})
1516+ result = df .replace ({"a" : {pd .Interval (0 , 1 ): "x" }})
1517+ expected = DataFrame ({"a" : ["x" , "x" ]}, dtype = object )
15131518 tm .assert_frame_equal (result , expected )
15141519
15151520 def test_replace_unicode (self ):
0 commit comments