diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index 48a3bfdab62c9..b12e117dcb373 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -1463,6 +1463,7 @@ Sparse - Bug in unary inversion operator (``~``) on a ``SparseSeries`` with boolean values. The performance of this has also been improved (:issue:`22835`) - Bug in :meth:`SparseArary.unique` not returning the unique values (:issue:`19595`) - Bug in :meth:`SparseArray.nonzero` and :meth:`SparseDataFrame.dropna` returning shifted/incorrect results (:issue:`21172`) +- Bug in :meth:`DataFrame.apply` where dtypes would lose sparseness (:issue:`23744`) Build Changes ^^^^^^^^^^^^^ @@ -1489,4 +1490,3 @@ Contributors ~~~~~~~~~~~~ .. contributors:: v0.23.4..HEAD - diff --git a/pandas/core/apply.py b/pandas/core/apply.py index c44e64d29ed26..5658094ec36c6 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -132,7 +132,7 @@ def get_result(self): # ufunc elif isinstance(self.f, np.ufunc): with np.errstate(all='ignore'): - results = self.f(self.values) + results = self.obj._data.apply('apply', func=self.f) return self.obj._constructor(data=results, index=self.index, columns=self.columns, copy=False) diff --git a/pandas/tests/sparse/frame/test_apply.py b/pandas/tests/sparse/frame/test_apply.py index 2d7a537f0fb3b..c26776ac4fd49 100644 --- a/pandas/tests/sparse/frame/test_apply.py +++ b/pandas/tests/sparse/frame/test_apply.py @@ -91,3 +91,14 @@ def test_applymap(frame): # just test that it works result = frame.applymap(lambda x: x * 2) assert isinstance(result, SparseDataFrame) + + +def test_apply_keep_sparse_dtype(): + # GH 23744 + sdf = SparseDataFrame(np.array([[0, 1, 0], [0, 0, 0], [0, 0, 1]]), + columns=['b', 'a', 'c'], default_fill_value=1) + df = DataFrame(sdf) + + expected = sdf.apply(np.exp) + result = df.apply(np.exp) + tm.assert_frame_equal(expected, result)