Skip to content

Commit 041b6b1

Browse files
charlesdong1991jschendel
authored andcommitted
Replace with nested dict raises for overlapping keys (#27696)
1 parent 49d2019 commit 041b6b1

File tree

3 files changed

+14
-11
lines changed

3 files changed

+14
-11
lines changed

doc/source/whatsnew/v1.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ ExtensionArray
207207
Other
208208
^^^^^
209209
- 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`)
210+
- 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`)
210211
- :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`)
211212

212213

pandas/core/generic.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -6669,11 +6669,7 @@ def replace(
66696669

66706670
for k, v in items:
66716671
keys, values = list(zip(*v.items())) or ([], [])
6672-
if set(keys) & set(values):
6673-
raise ValueError(
6674-
"Replacement not allowed with "
6675-
"overlapping keys and values"
6676-
)
6672+
66776673
to_rep_dict[k] = list(keys)
66786674
value_dict[k] = list(values)
66796675

pandas/tests/frame/test_replace.py

+12-6
Original file line numberDiff line numberDiff line change
@@ -1069,18 +1069,24 @@ def test_replace_truthy(self):
10691069
e = df
10701070
assert_frame_equal(r, e)
10711071

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

1077-
def test_replace_str_to_str_chain(self):
1077+
result = df.replace({"a": dict(zip(range(1, 5), range(2, 6)))})
1078+
expected = df.replace(dict(zip(range(1, 5), range(2, 6))))
1079+
assert_frame_equal(result, expected)
1080+
1081+
def test_nested_dict_overlapping_keys_replace_str(self):
1082+
# GH 27660
10781083
a = np.arange(1, 5)
10791084
astr = a.astype(str)
10801085
bstr = np.arange(2, 6).astype(str)
10811086
df = DataFrame({"a": astr})
1082-
with pytest.raises(ValueError, match="Replacement not allowed .+"):
1083-
df.replace({"a": dict(zip(astr, bstr))})
1087+
result = df.replace(dict(zip(astr, bstr)))
1088+
expected = df.replace({"a": dict(zip(astr, bstr))})
1089+
assert_frame_equal(result, expected)
10841090

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

0 commit comments

Comments
 (0)