Skip to content

Commit 0781fe5

Browse files
cpcloudjeffreystarr
authored andcommitted
BUG: fix replace bug where different dtypes in a nested dict would only replace the first value
1 parent a3400a4 commit 0781fe5

File tree

3 files changed

+21
-7
lines changed

3 files changed

+21
-7
lines changed

doc/source/release.rst

+2
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,8 @@ Bug Fixes
339339
coverted into bools. (:issue:`6806`)
340340
- Regression from 0.13 with ``fillna`` and a Series on datetime-like (:issue:`6344`)
341341
- Bug in adding np.timedelta64 to DatetimeIndex with tz outputs incorrect result (:issue:`6818`)
342+
- Bug in ``DataFrame.replace()`` where changing a dtype through replacement
343+
would only replace the first occurrence of a value (:issue:`6689`)
342344

343345
pandas 0.13.1
344346
-------------

pandas/core/generic.py

+8-7
Original file line numberDiff line numberDiff line change
@@ -2093,7 +2093,7 @@ def convert_objects(self, convert_dates=True, convert_numeric=False,
20932093
strings), non-convertibles get NaN
20942094
convert_timedeltas : if True, attempt to soft convert timedeltas, if 'coerce',
20952095
force conversion (and non-convertibles get NaT)
2096-
copy : Boolean, if True, return copy even if no copy is necessary
2096+
copy : Boolean, if True, return copy even if no copy is necessary
20972097
(e.g. no conversion was done), default is True.
20982098
It is meant for internal use, not to be confused with `inplace` kw.
20992099
@@ -2410,13 +2410,14 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None,
24102410
new_data = self._data
24112411
if is_dictlike(to_replace):
24122412
if is_dictlike(value): # {'A' : NA} -> {'A' : 0}
2413+
res = self if inplace else self.copy()
24132414
for c, src in compat.iteritems(to_replace):
24142415
if c in value and c in self:
2415-
new_data = new_data.replace(to_replace=src,
2416-
value=value[c],
2417-
filter=[c],
2418-
inplace=inplace,
2419-
regex=regex)
2416+
res[c] = res[c].replace(to_replace=src,
2417+
value=value[c],
2418+
inplace=False,
2419+
regex=regex)
2420+
return None if inplace else res
24202421

24212422
# {'A': NA} -> 0
24222423
elif not com.is_list_like(value):
@@ -2428,7 +2429,7 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None,
24282429
inplace=inplace,
24292430
regex=regex)
24302431
else:
2431-
raise TypeError('Fill value must be scalar, dict, or '
2432+
raise TypeError('value argument must be scalar, dict, or '
24322433
'Series')
24332434

24342435
elif com.is_list_like(to_replace): # [NA, ''] -> [0, 'missing']

pandas/tests/test_frame.py

+11
Original file line numberDiff line numberDiff line change
@@ -8231,6 +8231,17 @@ def test_replace_str_to_str_chain(self):
82318231
with tm.assertRaisesRegexp(ValueError, "Replacement not allowed .+"):
82328232
df.replace({'a': dict(zip(astr, bstr))})
82338233

8234+
def test_replace_swapping_bug(self):
8235+
df = pd.DataFrame({'a': [True, False, True]})
8236+
res = df.replace({'a': {True: 'Y', False: 'N'}})
8237+
expect = pd.DataFrame({'a': ['Y', 'N', 'Y']})
8238+
tm.assert_frame_equal(res, expect)
8239+
8240+
df = pd.DataFrame({'a': [0, 1, 0]})
8241+
res = df.replace({'a': {0: 'Y', 1: 'N'}})
8242+
expect = pd.DataFrame({'a': ['Y', 'N', 'Y']})
8243+
tm.assert_frame_equal(res, expect)
8244+
82348245
def test_combine_multiple_frames_dtypes(self):
82358246

82368247
# GH 2759

0 commit comments

Comments
 (0)