From c9a6017d1fac08218f61ccb8dbf4013639041b50 Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 14 Nov 2022 15:39:57 -0800 Subject: [PATCH 1/2] BUG: SparseArray.astype(np.int64) --- pandas/core/arrays/sparse/array.py | 25 +++++++++-------------- pandas/tests/arrays/sparse/test_astype.py | 9 ++++++++ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index b2fe02321ee0c..00631679e4fda 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -49,7 +49,10 @@ validate_insert_loc, ) -from pandas.core.dtypes.astype import astype_nansafe +from pandas.core.dtypes.astype import ( + astype_array, + astype_nansafe, +) from pandas.core.dtypes.cast import ( construct_1d_arraylike_from_scalar, find_common_type, @@ -90,6 +93,7 @@ from pandas.core.base import PandasObject import pandas.core.common as com from pandas.core.construction import ( + ensure_wrapped_if_datetimelike, extract_array, sanitize_array, ) @@ -120,8 +124,6 @@ class ellipsis(Enum): SparseIndexKind = Literal["integer", "block"] - from pandas.core.dtypes.dtypes import ExtensionDtype - from pandas import Series else: @@ -1305,23 +1307,16 @@ def astype(self, dtype: AstypeArg | None = None, copy: bool = True): future_dtype = pandas_dtype(dtype) if not isinstance(future_dtype, SparseDtype): # GH#34457 - if isinstance(future_dtype, np.dtype): - values = np.array(self) - return astype_nansafe(values, dtype=future_dtype) - else: - dtype = cast(ExtensionDtype, dtype) - cls = dtype.construct_array_type() - return cls._from_sequence(self, dtype=dtype, copy=copy) + values = np.asarray(self) + values = ensure_wrapped_if_datetimelike(values) + return astype_array(values, dtype=future_dtype, copy=False) dtype = self.dtype.update_dtype(dtype) subtype = pandas_dtype(dtype._subtype_with_str) + subtype = cast(np.dtype, subtype) # ensured by update_dtype sp_values = astype_nansafe(self.sp_values, subtype, copy=copy) - # error: Argument 1 to "_simple_new" of "SparseArray" has incompatible type - # "ExtensionArray"; expected "ndarray" - return self._simple_new( - sp_values, self.sp_index, dtype # type: ignore[arg-type] - ) + return self._simple_new(sp_values, self.sp_index, dtype) def map(self: SparseArrayT, mapper) -> SparseArrayT: """ diff --git a/pandas/tests/arrays/sparse/test_astype.py b/pandas/tests/arrays/sparse/test_astype.py index 8751b9bb294ae..924f7a56e806a 100644 --- a/pandas/tests/arrays/sparse/test_astype.py +++ b/pandas/tests/arrays/sparse/test_astype.py @@ -110,3 +110,12 @@ def test_astype_copy_false(self): result = arr.astype(dtype, copy=False) expected = SparseArray([1.0, 2.0, 3.0], fill_value=0.0) tm.assert_sp_array_equal(result, expected) + + def test_astype_dt64_to_int64(self): + # GH#49631 match non-sparse behavior + values = np.array(["NaT", "2016-01-02", "2016-01-03"], dtype="M8[ns]") + + arr = SparseArray(values) + result = arr.astype("int64") + expected = values.astype("int64") + tm.assert_numpy_array_equal(result, expected) From 26676125ec4939d0b10a549c7634bf8a8c023381 Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 14 Nov 2022 15:41:43 -0800 Subject: [PATCH 2/2] whatsnew --- doc/source/whatsnew/v2.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 032bcf09244e5..e8b7673773bf5 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -718,7 +718,7 @@ Reshaping Sparse ^^^^^^ -- +- Bug in :meth:`Series.astype` when converting a ``SparseDtype`` with ``datetime64[ns]`` subtype to ``int64`` dtype raising, inconsistent with the non-sparse behavior (:issue:`49631`) - ExtensionArray