Skip to content

Commit 87d26ba

Browse files
jbrockmendelTomAugspurger
authored andcommitted
PERF: replace with list, closes #28084 (#28099)
1 parent bca39a7 commit 87d26ba

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

asv_bench/benchmarks/replace.py

+17
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,23 @@ def time_replace_series(self, inplace):
3636
self.s.replace(self.to_rep, inplace=inplace)
3737

3838

39+
class ReplaceList:
40+
# GH#28099
41+
42+
params = [(True, False)]
43+
param_names = ["inplace"]
44+
45+
def setup(self, inplace):
46+
self.df = pd.DataFrame({"A": 0, "B": 0}, index=range(4 * 10 ** 7))
47+
48+
def time_replace_list(self, inplace):
49+
self.df.replace([np.inf, -np.inf], np.nan, inplace=inplace)
50+
51+
def time_replace_list_one_match(self, inplace):
52+
# the 1 can be held in self._df.blocks[0], while the inf and -inf cant
53+
self.df.replace([np.inf, -np.inf, 1], np.nan, inplace=inplace)
54+
55+
3956
class Convert:
4057

4158
params = (["DataFrame", "Series"], ["Timestamp", "Timedelta"])

pandas/core/internals/blocks.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,26 @@ def replace(
743743
return [self]
744744
return [self.copy()]
745745

746+
to_replace = [x for x in to_replace if self._can_hold_element(x)]
747+
if not len(to_replace):
748+
# GH#28084 avoid costly checks since we can infer
749+
# that there is nothing to replace in this block
750+
if inplace:
751+
return [self]
752+
return [self.copy()]
753+
754+
if len(to_replace) == 1:
755+
# _can_hold_element checks have reduced this back to the
756+
# scalar case and we can avoid a costly object cast
757+
return self.replace(
758+
to_replace[0],
759+
value,
760+
inplace=inplace,
761+
filter=filter,
762+
regex=regex,
763+
convert=convert,
764+
)
765+
746766
# GH 22083, TypeError or ValueError occurred within error handling
747767
# causes infinite loop. Cast and retry only if not objectblock.
748768
if is_object_dtype(self):
@@ -751,7 +771,7 @@ def replace(
751771
# try again with a compatible block
752772
block = self.astype(object)
753773
return block.replace(
754-
to_replace=original_to_replace,
774+
to_replace=to_replace,
755775
value=value,
756776
inplace=inplace,
757777
filter=filter,

0 commit comments

Comments
 (0)