Skip to content

Commit 736552c

Browse files
committed
Merge pull request #6429 from cpcloud/replace-mapping-punt-5338
BUG: punt to user when passing overlapping replacement values in a nested dict
2 parents aec3899 + e2e04ce commit 736552c

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

doc/source/release.rst

+2
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ Bug Fixes
164164
- ``eval``/``query`` expressions with strings containing the ``@`` character
165165
will now work (:issue:`6366`).
166166
- Bug in ``Series.reindex`` when specifying a ``method`` with some nan values was inconsistent (noted on a resample) (:issue:`6418`)
167+
- Bug in :meth:`DataFrame.replace` where nested dicts were erroneously
168+
depending on the order of dictionary keys and values (:issue:`5338`).
167169

168170
pandas 0.13.1
169171
-------------

pandas/core/generic.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -2327,8 +2327,12 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None,
23272327
value_dict = {}
23282328

23292329
for k, v in items:
2330-
to_rep_dict[k] = list(v.keys())
2331-
value_dict[k] = list(v.values())
2330+
keys, values = zip(*v.items())
2331+
if set(keys) & set(values):
2332+
raise ValueError("Replacement not allowed with "
2333+
"overlapping keys and values")
2334+
to_rep_dict[k] = list(keys)
2335+
value_dict[k] = list(values)
23322336

23332337
to_replace, value = to_rep_dict, value_dict
23342338
else:

pandas/tests/test_frame.py

+13
Original file line numberDiff line numberDiff line change
@@ -8089,6 +8089,19 @@ def test_replace_with_dict_with_bool_keys(self):
80898089
with tm.assertRaisesRegexp(TypeError, 'Cannot compare types .+'):
80908090
df.replace({'asdf': 'asdb', True: 'yes'})
80918091

8092+
def test_replace_int_to_int_chain(self):
8093+
df = DataFrame({'a': lrange(1, 5)})
8094+
with tm.assertRaisesRegexp(ValueError, "Replacement not allowed .+"):
8095+
df.replace({'a': dict(zip(range(1, 5), range(2, 6)))})
8096+
8097+
def test_replace_str_to_str_chain(self):
8098+
a = np.arange(1, 5)
8099+
astr = a.astype(str)
8100+
bstr = np.arange(2, 6).astype(str)
8101+
df = DataFrame({'a': astr})
8102+
with tm.assertRaisesRegexp(ValueError, "Replacement not allowed .+"):
8103+
df.replace({'a': dict(zip(astr, bstr))})
8104+
80928105
def test_combine_multiple_frames_dtypes(self):
80938106

80948107
# GH 2759

0 commit comments

Comments
 (0)