Skip to content

Commit

Permalink
BUG: NDFrame.replace wrong exception type, wrong return when size==0 (#…
Browse files Browse the repository at this point in the history
…36045)

* REF: remove unnecesary try/except

* TST: add test for agg on ordered categorical cols (#35630)

* TST: resample does not yield empty groups (#10603) (#35799)

* revert accidental rebase

* BUG: NDFrame.replace wrong exception type, wrong return when size==0

* bool->bool_t

* whatsnew

Co-authored-by: Karthik Mathur <[email protected]>
Co-authored-by: tkmz-n <[email protected]>
  • Loading branch information
3 people authored Sep 2, 2020
1 parent 2056900 commit 73c1d32
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 7 deletions.
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v1.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ ExtensionArray

Other
^^^^^
-
- Bug in :meth:`DataFrame.replace` and :meth:`Series.replace` incorrectly raising ``AssertionError`` instead of ``ValueError`` when invalid parameter combinations are passed (:issue:`36045`)
-

.. ---------------------------------------------------------------------------
Expand Down
14 changes: 8 additions & 6 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -6179,8 +6179,8 @@ def replace(
self,
to_replace=None,
value=None,
inplace=False,
limit=None,
inplace: bool_t = False,
limit: Optional[int] = None,
regex=False,
method="pad",
):
Expand Down Expand Up @@ -6256,7 +6256,7 @@ def replace(
If True, in place. Note: this will modify any
other views on this object (e.g. a column from a DataFrame).
Returns the caller if this is True.
limit : int, default None
limit : int or None, default None
Maximum size gap to forward or backward fill.
regex : bool or same types as `to_replace`, default False
Whether to interpret `to_replace` and/or `value` as regular
Expand Down Expand Up @@ -6490,7 +6490,7 @@ def replace(

inplace = validate_bool_kwarg(inplace, "inplace")
if not is_bool(regex) and to_replace is not None:
raise AssertionError("'to_replace' must be 'None' if 'regex' is not a bool")
raise ValueError("'to_replace' must be 'None' if 'regex' is not a bool")

if value is None:
# passing a single value that is scalar like
Expand Down Expand Up @@ -6550,12 +6550,14 @@ def replace(

# need a non-zero len on all axes
if not self.size:
return self
if inplace:
return
return self.copy()

if is_dict_like(to_replace):
if is_dict_like(value): # {'A' : NA} -> {'A' : 0}
# Note: Checking below for `in foo.keys()` instead of
# `in foo`is needed for when we have a Series and not dict
# `in foo` is needed for when we have a Series and not dict
mapping = {
col: (to_replace[col], value[col])
for col in to_replace.keys()
Expand Down
23 changes: 23 additions & 0 deletions pandas/tests/series/methods/test_replace.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,29 @@ def test_replace_invalid_to_replace(self):
with pytest.raises(TypeError, match=msg):
series.replace(lambda x: x.strip())

@pytest.mark.parametrize("frame", [False, True])
def test_replace_nonbool_regex(self, frame):
obj = pd.Series(["a", "b", "c "])
if frame:
obj = obj.to_frame()

msg = "'to_replace' must be 'None' if 'regex' is not a bool"
with pytest.raises(ValueError, match=msg):
obj.replace(to_replace=["a"], regex="foo")

@pytest.mark.parametrize("frame", [False, True])
def test_replace_empty_copy(self, frame):
obj = pd.Series([], dtype=np.float64)
if frame:
obj = obj.to_frame()

res = obj.replace(4, 5, inplace=True)
assert res is None

res = obj.replace(4, 5, inplace=False)
tm.assert_equal(res, obj)
assert res is not obj

def test_replace_only_one_dictlike_arg(self):
# GH#33340

Expand Down

0 comments on commit 73c1d32

Please sign in to comment.