Skip to content

Commit cca262d

Browse files
authored
BUG: SparseArray.astype(np.int64) (#49704)
* BUG: SparseArray.astype(np.int64) * whatsnew
1 parent a37b78d commit cca262d

File tree

3 files changed

+20
-17
lines changed

3 files changed

+20
-17
lines changed

doc/source/whatsnew/v2.0.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ Reshaping
730730

731731
Sparse
732732
^^^^^^
733-
-
733+
- 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`)
734734
-
735735

736736
ExtensionArray

pandas/core/arrays/sparse/array.py

+10-16
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@
4949
validate_insert_loc,
5050
)
5151

52-
from pandas.core.dtypes.astype import astype_nansafe
52+
from pandas.core.dtypes.astype import (
53+
astype_array,
54+
astype_nansafe,
55+
)
5356
from pandas.core.dtypes.cast import (
5457
construct_1d_arraylike_from_scalar,
5558
find_common_type,
@@ -90,6 +93,7 @@
9093
from pandas.core.base import PandasObject
9194
import pandas.core.common as com
9295
from pandas.core.construction import (
96+
ensure_wrapped_if_datetimelike,
9397
extract_array,
9498
sanitize_array,
9599
)
@@ -120,8 +124,6 @@ class ellipsis(Enum):
120124

121125
SparseIndexKind = Literal["integer", "block"]
122126

123-
from pandas.core.dtypes.dtypes import ExtensionDtype
124-
125127
from pandas import Series
126128

127129
else:
@@ -1305,24 +1307,16 @@ def astype(self, dtype: AstypeArg | None = None, copy: bool = True):
13051307
future_dtype = pandas_dtype(dtype)
13061308
if not isinstance(future_dtype, SparseDtype):
13071309
# GH#34457
1308-
if isinstance(future_dtype, np.dtype):
1309-
values = np.array(self)
1310-
return astype_nansafe(values, dtype=future_dtype)
1311-
else:
1312-
# pylint: disable-next=used-before-assignment
1313-
dtype = cast(ExtensionDtype, dtype)
1314-
cls = dtype.construct_array_type()
1315-
return cls._from_sequence(self, dtype=dtype, copy=copy)
1310+
values = np.asarray(self)
1311+
values = ensure_wrapped_if_datetimelike(values)
1312+
return astype_array(values, dtype=future_dtype, copy=False)
13161313

13171314
dtype = self.dtype.update_dtype(dtype)
13181315
subtype = pandas_dtype(dtype._subtype_with_str)
1316+
subtype = cast(np.dtype, subtype) # ensured by update_dtype
13191317
sp_values = astype_nansafe(self.sp_values, subtype, copy=copy)
13201318

1321-
# error: Argument 1 to "_simple_new" of "SparseArray" has incompatible type
1322-
# "ExtensionArray"; expected "ndarray"
1323-
return self._simple_new(
1324-
sp_values, self.sp_index, dtype # type: ignore[arg-type]
1325-
)
1319+
return self._simple_new(sp_values, self.sp_index, dtype)
13261320

13271321
def map(self: SparseArrayT, mapper) -> SparseArrayT:
13281322
"""

pandas/tests/arrays/sparse/test_astype.py

+9
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,12 @@ def test_astype_copy_false(self):
110110
result = arr.astype(dtype, copy=False)
111111
expected = SparseArray([1.0, 2.0, 3.0], fill_value=0.0)
112112
tm.assert_sp_array_equal(result, expected)
113+
114+
def test_astype_dt64_to_int64(self):
115+
# GH#49631 match non-sparse behavior
116+
values = np.array(["NaT", "2016-01-02", "2016-01-03"], dtype="M8[ns]")
117+
118+
arr = SparseArray(values)
119+
result = arr.astype("int64")
120+
expected = values.astype("int64")
121+
tm.assert_numpy_array_equal(result, expected)

0 commit comments

Comments
 (0)