Skip to content

REGR: only convert at end for Block.replace_list #46393

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

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,8 @@ def replace(
to_replace,
value,
inplace: bool = False,
# conversion is done at the end if we're called from replace_list
convert: bool = True,
# mask may be pre-computed if we're called from replace_list
mask: npt.NDArray[np.bool_] | None = None,
) -> list[Block]:
Expand All @@ -572,6 +574,7 @@ def replace(
if isinstance(values, Categorical):
# TODO: avoid special-casing
blk = self if inplace else self.copy()
# TODO: should we pass convert here? moot point if special casing avoided.
blk.values._replace(to_replace=to_replace, value=value, inplace=True)
return [blk]

Expand All @@ -592,7 +595,7 @@ def replace(
elif self._can_hold_element(value):
blk = self if inplace else self.copy()
putmask_inplace(blk.values, mask, value)
if not (self.is_object and value is None):
if convert and not (self.is_object and value is None):
# if the user *explicitly* gave None, we keep None, otherwise
# may downcast to NaN
blocks = blk.convert(numeric=False, copy=False)
Expand All @@ -606,6 +609,7 @@ def replace(
to_replace=to_replace,
value=value,
inplace=True,
convert=convert,
mask=mask,
)

Expand All @@ -619,6 +623,7 @@ def replace(
to_replace=to_replace,
value=value,
inplace=True,
convert=convert,
mask=mask[i : i + 1],
)
)
Expand All @@ -630,8 +635,10 @@ def _replace_regex(
to_replace,
value,
inplace: bool = False,
# conversion is done at the end if we're called from replace_list
convert: bool = True,
mask=None,
# mask may be pre-computed if we're called from replace_list
mask: npt.NDArray[np.bool_] | None = None,
) -> list[Block]:
"""
Replace elements by the given value.
Expand Down Expand Up @@ -664,7 +671,10 @@ def _replace_regex(
replace_regex(new_values, rx, value, mask)

block = self.make_block(new_values)
return block.convert(numeric=False, copy=False)
if convert:
return block.convert(numeric=False, copy=False)
else:
return [block]

@final
def replace_list(
Expand Down Expand Up @@ -707,7 +717,7 @@ def replace_list(
masks = [extract_bool_array(x) for x in masks] # type: ignore[arg-type]

rb = [self if inplace else self.copy()]
for i, (src, dest) in enumerate(pairs):
for i, (to_replace, value) in enumerate(pairs):
convert = i == src_len # only convert once at the end
new_rb: list[Block] = []

Expand All @@ -723,8 +733,8 @@ def replace_list(
m = mib[blk_num : blk_num + 1]

result = blk._replace_coerce(
to_replace=src,
value=dest,
to_replace=to_replace,
value=value,
mask=m,
inplace=inplace,
regex=regex,
Expand Down Expand Up @@ -785,7 +795,11 @@ def _replace_coerce(
putmask_inplace(nb.values, mask, value)
return [nb]
return self.replace(
to_replace=to_replace, value=value, inplace=inplace, mask=mask
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the dispatch to self.replace which converted by default, and didn't have convert parameter.

to_replace=to_replace,
value=value,
inplace=inplace,
convert=False,
mask=mask,
)

# ---------------------------------------------------------------------
Expand Down