From 3d74aef9a70b2974e2f2eec695dcf8da46b52083 Mon Sep 17 00:00:00 2001 From: Brock Date: Fri, 28 Jan 2022 16:06:40 -0800 Subject: [PATCH 1/3] BUG: Series[sparse].where losing fill_value --- doc/source/whatsnew/v1.5.0.rst | 2 +- pandas/core/arrays/sparse/array.py | 2 +- pandas/tests/arrays/sparse/test_array.py | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index 1d4054d5ea0f1..8b6b919a9e68b 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -316,7 +316,7 @@ Reshaping Sparse ^^^^^^ -- +- Bug in :meth:`Series.where` and :meth:`DataFrame.where` with ``SparseDtype`` failing to retain the array's ``fill_value`` (:issue:`??`) - ExtensionArray diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index 18621fa9fb68a..ca31204fa28d5 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -1355,7 +1355,7 @@ def _where(self, mask, value): # NB: may not preserve dtype, e.g. result may be Sparse[float64] # while self is Sparse[int64] naive_implementation = np.where(mask, self, value) - result = type(self)._from_sequence(naive_implementation) + result = type(self)._from_sequence(naive_implementation, dtype=self.dtype) return result # ------------------------------------------------------------------------ diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index a8517535e7833..642025d3fe1bf 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -880,6 +880,20 @@ def test_generator_warnings(self): pass assert len(w) == 0 + def test_where_retain_fill_value(self): + # don't lose fill_value on _where + arr = SparseArray([np.nan, 1.0], fill_value=0) + + mask = np.array([True, False]) + + res = arr._where(~mask, 1) + exp = SparseArray([1, 1.0], fill_value=0) + tm.assert_sp_array_equal(res, exp) + + ser = pd.Series(arr) + res = ser.where(~mask, 1) + tm.assert_series_equal(res, pd.Series(exp)) + def test_fillna(self): s = SparseArray([1, np.nan, np.nan, 3, np.nan]) res = s.fillna(-1) From bef5e98234506b1d53f85dd84257f9f763da9e0f Mon Sep 17 00:00:00 2001 From: Brock Date: Fri, 28 Jan 2022 16:07:26 -0800 Subject: [PATCH 2/3] GH refs --- doc/source/whatsnew/v1.5.0.rst | 2 +- pandas/tests/arrays/sparse/test_array.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index 8b6b919a9e68b..59185690677dc 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -316,7 +316,7 @@ Reshaping Sparse ^^^^^^ -- Bug in :meth:`Series.where` and :meth:`DataFrame.where` with ``SparseDtype`` failing to retain the array's ``fill_value`` (:issue:`??`) +- Bug in :meth:`Series.where` and :meth:`DataFrame.where` with ``SparseDtype`` failing to retain the array's ``fill_value`` (:issue:`45691`) - ExtensionArray diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index 642025d3fe1bf..baa7537e3cc2f 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -881,7 +881,7 @@ def test_generator_warnings(self): assert len(w) == 0 def test_where_retain_fill_value(self): - # don't lose fill_value on _where + # GH#45691 don't lose fill_value on _where arr = SparseArray([np.nan, 1.0], fill_value=0) mask = np.array([True, False]) From 7095a5040fcc54489848c686406b1ed8d459320d Mon Sep 17 00:00:00 2001 From: Brock Date: Fri, 28 Jan 2022 16:55:51 -0800 Subject: [PATCH 3/3] typo fixup --- pandas/core/arrays/sparse/array.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index ca31204fa28d5..bedde2dbf2558 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -1355,7 +1355,8 @@ def _where(self, mask, value): # NB: may not preserve dtype, e.g. result may be Sparse[float64] # while self is Sparse[int64] naive_implementation = np.where(mask, self, value) - result = type(self)._from_sequence(naive_implementation, dtype=self.dtype) + dtype = SparseDtype(naive_implementation.dtype, fill_value=self.fill_value) + result = type(self)._from_sequence(naive_implementation, dtype=dtype) return result # ------------------------------------------------------------------------