From 05564f6b8e661adfb515070e857cef794580d7ea Mon Sep 17 00:00:00 2001 From: Luke Manley Date: Tue, 23 Jan 2024 06:17:01 -0500 Subject: [PATCH 1/2] fix perf regression in Series.combine_first --- doc/source/whatsnew/v2.2.1.rst | 1 + pandas/core/series.py | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/doc/source/whatsnew/v2.2.1.rst b/doc/source/whatsnew/v2.2.1.rst index 75445c978d262..3b9026ad26d20 100644 --- a/doc/source/whatsnew/v2.2.1.rst +++ b/doc/source/whatsnew/v2.2.1.rst @@ -13,6 +13,7 @@ including other versions of pandas. Fixed regressions ~~~~~~~~~~~~~~~~~ +- Fixed performance regression in :meth:`Series.combine_first` (:issue:`55845`) - Fixed regression in :func:`merge_ordered` raising ``TypeError`` for ``fill_method="ffill"`` and ``how="left"`` (:issue:`57010`) .. --------------------------------------------------------------------------- diff --git a/pandas/core/series.py b/pandas/core/series.py index 0e1e9c964632e..229ee1d29668b 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -3514,6 +3514,13 @@ def combine_first(self, other) -> Series: """ from pandas.core.reshape.concat import concat + if self.dtype == other.dtype: + if self.index.equals(other.index): + return self.fillna(other) + elif self._can_hold_na: + this, other = self.align(other, join="outer") + return this.fillna(other) + new_index = self.index.union(other.index) this = self From 8203efd3548edc8684c056ec13151fe3c70bf12d Mon Sep 17 00:00:00 2001 From: Luke Manley Date: Tue, 23 Jan 2024 17:25:14 -0500 Subject: [PATCH 2/2] fix --- pandas/core/series.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index 229ee1d29668b..95c53fe9fadc8 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -87,6 +87,7 @@ from pandas.core.dtypes.dtypes import ( CategoricalDtype, ExtensionDtype, + SparseDtype, ) from pandas.core.dtypes.generic import ( ABCDataFrame, @@ -3516,10 +3517,10 @@ def combine_first(self, other) -> Series: if self.dtype == other.dtype: if self.index.equals(other.index): - return self.fillna(other) - elif self._can_hold_na: + return self.mask(self.isna(), other) + elif self._can_hold_na and not isinstance(self.dtype, SparseDtype): this, other = self.align(other, join="outer") - return this.fillna(other) + return this.mask(this.isna(), other) new_index = self.index.union(other.index)