diff --git a/doc/source/release.rst b/doc/source/release.rst index 20269f407e0f3..13588a771f3c0 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -336,6 +336,8 @@ Bug Fixes coverted into bools. (:issue:`6806`) - Regression from 0.13 with ``fillna`` and a Series on datetime-like (:issue:`6344`) - Bug in adding np.timedelta64 to DatetimeIndex with tz outputs incorrect result (:issue:`6818`) +- Bug in ``DataFrame.replace()`` where changing a dtype through replacement + would only replace the first occurrence of a value (:issue:`6689`) pandas 0.13.1 ------------- diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 8ec4655c0a309..7e5e125034189 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -2093,7 +2093,7 @@ def convert_objects(self, convert_dates=True, convert_numeric=False, strings), non-convertibles get NaN convert_timedeltas : if True, attempt to soft convert timedeltas, if 'coerce', force conversion (and non-convertibles get NaT) - copy : Boolean, if True, return copy even if no copy is necessary + copy : Boolean, if True, return copy even if no copy is necessary (e.g. no conversion was done), default is True. It is meant for internal use, not to be confused with `inplace` kw. @@ -2410,13 +2410,14 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None, new_data = self._data if is_dictlike(to_replace): if is_dictlike(value): # {'A' : NA} -> {'A' : 0} + res = self if inplace else self.copy() for c, src in compat.iteritems(to_replace): if c in value and c in self: - new_data = new_data.replace(to_replace=src, - value=value[c], - filter=[c], - inplace=inplace, - regex=regex) + res[c] = res[c].replace(to_replace=src, + value=value[c], + inplace=False, + regex=regex) + return None if inplace else res # {'A': NA} -> 0 elif not com.is_list_like(value): @@ -2428,7 +2429,7 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None, inplace=inplace, regex=regex) else: - raise TypeError('Fill value must be scalar, dict, or ' + raise TypeError('value argument must be scalar, dict, or ' 'Series') elif com.is_list_like(to_replace): # [NA, ''] -> [0, 'missing'] diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py index 0a7100ce091c5..aa8350dfdfe78 100644 --- a/pandas/tests/test_frame.py +++ b/pandas/tests/test_frame.py @@ -8231,6 +8231,17 @@ def test_replace_str_to_str_chain(self): with tm.assertRaisesRegexp(ValueError, "Replacement not allowed .+"): df.replace({'a': dict(zip(astr, bstr))}) + def test_replace_swapping_bug(self): + df = pd.DataFrame({'a': [True, False, True]}) + res = df.replace({'a': {True: 'Y', False: 'N'}}) + expect = pd.DataFrame({'a': ['Y', 'N', 'Y']}) + tm.assert_frame_equal(res, expect) + + df = pd.DataFrame({'a': [0, 1, 0]}) + res = df.replace({'a': {0: 'Y', 1: 'N'}}) + expect = pd.DataFrame({'a': ['Y', 'N', 'Y']}) + tm.assert_frame_equal(res, expect) + def test_combine_multiple_frames_dtypes(self): # GH 2759