Skip to content

Commit ef37bec

Browse files
jbrockmendelKevin D Smith
authored and
Kevin D Smith
committed
REF: implement Block._replace_list (pandas-dev#36020)
1 parent 3762058 commit ef37bec

File tree

2 files changed

+52
-30
lines changed

2 files changed

+52
-30
lines changed

pandas/core/internals/blocks.py

+37
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,43 @@ def _replace_single(self, *args, **kwargs):
788788
""" no-op on a non-ObjectBlock """
789789
return self if kwargs["inplace"] else self.copy()
790790

791+
def _replace_list(
792+
self,
793+
src_list: List[Any],
794+
dest_list: List[Any],
795+
masks: List[np.ndarray],
796+
inplace: bool = False,
797+
regex: bool = False,
798+
) -> List["Block"]:
799+
"""
800+
See BlockManager._replace_list docstring.
801+
"""
802+
src_len = len(src_list) - 1
803+
804+
rb = [self if inplace else self.copy()]
805+
for i, (src, dest) in enumerate(zip(src_list, dest_list)):
806+
new_rb: List["Block"] = []
807+
for blk in rb:
808+
m = masks[i][blk.mgr_locs.indexer]
809+
convert = i == src_len # only convert once at the end
810+
result = blk._replace_coerce(
811+
mask=m,
812+
to_replace=src,
813+
value=dest,
814+
inplace=inplace,
815+
convert=convert,
816+
regex=regex,
817+
)
818+
if m.any() or convert:
819+
if isinstance(result, list):
820+
new_rb.extend(result)
821+
else:
822+
new_rb.append(result)
823+
else:
824+
new_rb.append(blk)
825+
rb = new_rb
826+
return rb
827+
791828
def setitem(self, indexer, value):
792829
"""
793830
Attempt self.values[indexer] = value, possibly creating a new array.

pandas/core/internals/managers.py

+15-30
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import operator
44
import re
55
from typing import (
6+
Any,
67
DefaultDict,
78
Dict,
89
List,
@@ -600,8 +601,12 @@ def replace(self, value, **kwargs) -> "BlockManager":
600601
return self.apply("replace", value=value, **kwargs)
601602

602603
def replace_list(
603-
self, src_list, dest_list, inplace: bool = False, regex: bool = False
604-
) -> "BlockManager":
604+
self: T,
605+
src_list: List[Any],
606+
dest_list: List[Any],
607+
inplace: bool = False,
608+
regex: bool = False,
609+
) -> T:
605610
""" do a list replace """
606611
inplace = validate_bool_kwarg(inplace, "inplace")
607612

@@ -625,34 +630,14 @@ def comp(s: Scalar, mask: np.ndarray, regex: bool = False):
625630

626631
masks = [comp(s, mask, regex) for s in src_list]
627632

628-
result_blocks = []
629-
src_len = len(src_list) - 1
630-
for blk in self.blocks:
631-
632-
# its possible to get multiple result blocks here
633-
# replace ALWAYS will return a list
634-
rb = [blk if inplace else blk.copy()]
635-
for i, (s, d) in enumerate(zip(src_list, dest_list)):
636-
new_rb: List[Block] = []
637-
for b in rb:
638-
m = masks[i][b.mgr_locs.indexer]
639-
convert = i == src_len # only convert once at the end
640-
result = b._replace_coerce(
641-
mask=m,
642-
to_replace=s,
643-
value=d,
644-
inplace=inplace,
645-
convert=convert,
646-
regex=regex,
647-
)
648-
if m.any() or convert:
649-
new_rb = _extend_blocks(result, new_rb)
650-
else:
651-
new_rb.append(b)
652-
rb = new_rb
653-
result_blocks.extend(rb)
654-
655-
bm = type(self).from_blocks(result_blocks, self.axes)
633+
bm = self.apply(
634+
"_replace_list",
635+
src_list=src_list,
636+
dest_list=dest_list,
637+
masks=masks,
638+
inplace=inplace,
639+
regex=regex,
640+
)
656641
bm._consolidate_inplace()
657642
return bm
658643

0 commit comments

Comments
 (0)