Skip to content

Commit

Permalink
Replace with nested dict raises for overlapping keys (pandas-dev#27696)
Browse files Browse the repository at this point in the history
  • Loading branch information
charlesdong1991 authored and proost committed Dec 19, 2019
1 parent d374387 commit 3fd0e2b
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 11 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ ExtensionArray
Other
^^^^^
- Trying to set the ``display.precision``, ``display.max_rows`` or ``display.max_columns`` using :meth:`set_option` to anything but a ``None`` or a positive int will raise a ``ValueError`` (:issue:`23348`)
- Using :meth:`DataFrame.replace` with overlapping keys in a nested dictionary will no longer raise, now matching the behavior of a flat dictionary (:issue:`27660`)
- :meth:`DataFrame.to_csv` and :meth:`Series.to_csv` now support dicts as ``compression`` argument with key ``'method'`` being the compression method and others as additional compression options when the compression method is ``'zip'``. (:issue:`26023`)


Expand Down
6 changes: 1 addition & 5 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -6669,11 +6669,7 @@ def replace(

for k, v in items:
keys, values = list(zip(*v.items())) or ([], [])
if set(keys) & set(values):
raise ValueError(
"Replacement not allowed with "
"overlapping keys and values"
)

to_rep_dict[k] = list(keys)
value_dict[k] = list(values)

Expand Down
18 changes: 12 additions & 6 deletions pandas/tests/frame/test_replace.py
Original file line number Diff line number Diff line change
Expand Up @@ -1069,18 +1069,24 @@ def test_replace_truthy(self):
e = df
assert_frame_equal(r, e)

def test_replace_int_to_int_chain(self):
def test_nested_dict_overlapping_keys_replace_int(self):
# GH 27660 keep behaviour consistent for simple dictionary and
# nested dictionary replacement
df = DataFrame({"a": list(range(1, 5))})
with pytest.raises(ValueError, match="Replacement not allowed .+"):
df.replace({"a": dict(zip(range(1, 5), range(2, 6)))})

def test_replace_str_to_str_chain(self):
result = df.replace({"a": dict(zip(range(1, 5), range(2, 6)))})
expected = df.replace(dict(zip(range(1, 5), range(2, 6))))
assert_frame_equal(result, expected)

def test_nested_dict_overlapping_keys_replace_str(self):
# GH 27660
a = np.arange(1, 5)
astr = a.astype(str)
bstr = np.arange(2, 6).astype(str)
df = DataFrame({"a": astr})
with pytest.raises(ValueError, match="Replacement not allowed .+"):
df.replace({"a": dict(zip(astr, bstr))})
result = df.replace(dict(zip(astr, bstr)))
expected = df.replace({"a": dict(zip(astr, bstr))})
assert_frame_equal(result, expected)

def test_replace_swapping_bug(self):
df = pd.DataFrame({"a": [True, False, True]})
Expand Down

0 comments on commit 3fd0e2b

Please sign in to comment.