Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLN: short-circuit case in Block.replace #27768

Merged
merged 8 commits into from Aug 12, 2019
21 changes: 19 additions & 2 deletions pandas/core/internals/blocks.py
Expand Up @@ -772,8 +772,11 @@ def replace(
# If we cannot replace with own dtype, convert to ObjectBlock and
# retry
if not self._can_hold_element(to_replace):
# TODO: we should be able to infer at this point that there is
# nothing to replace
if not isinstance(to_replace, list):
if inplace:
return [self]
return [self.copy()]

# GH 22083, TypeError or ValueError occurred within error handling
# causes infinite loop. Cast and retry only if not objectblock.
if is_object_dtype(self):
Expand All @@ -798,14 +801,27 @@ def replace(
filtered_out = ~self.mgr_locs.isin(filter)
mask[filtered_out.nonzero()[0]] = False

if not mask.any():
if inplace:
return [self]
return [self.copy()]

try:
blocks = self.putmask(mask, value, inplace=inplace)
# Note: it is _not_ the case that self._can_hold_element(value)
# is always true at this point. In particular, that can fail
# for:
# "2u" with bool-dtype, float-dtype
# 0.5 with int64-dtype
# np.nan with int64-dtype
except (TypeError, ValueError):
# GH 22083, TypeError or ValueError occurred within error handling
# causes infinite loop. Cast and retry only if not objectblock.
if is_object_dtype(self):
raise

assert not self._can_hold_element(value), value

TomAugspurger marked this conversation as resolved.
Show resolved Hide resolved
# try again with a compatible block
block = self.astype(object)
return block.replace(
Expand Down Expand Up @@ -960,6 +976,7 @@ def putmask(self, mask, new, align=True, inplace=False, axis=0, transpose=False)

# if we are passed a scalar None, convert it here
if not is_list_like(new) and isna(new) and not self.is_object:
# FIXME: make sure we have compatible NA
new = self.fill_value

if self._can_hold_element(new):
Expand Down