|
1 | 1 | """
|
2 | 2 | Utility functions related to concat.
|
3 | 3 | """
|
4 |
| -from typing import cast |
| 4 | +from typing import ( |
| 5 | + TYPE_CHECKING, |
| 6 | + cast, |
| 7 | +) |
5 | 8 |
|
6 | 9 | import numpy as np
|
7 | 10 |
|
|
10 | 13 | DtypeObj,
|
11 | 14 | )
|
12 | 15 |
|
13 |
| -from pandas.core.dtypes.cast import find_common_type |
| 16 | +from pandas.core.dtypes.cast import ( |
| 17 | + astype_array, |
| 18 | + find_common_type, |
| 19 | +) |
14 | 20 | from pandas.core.dtypes.common import (
|
15 | 21 | is_categorical_dtype,
|
16 | 22 | is_dtype_equal,
|
|
19 | 25 | from pandas.core.dtypes.dtypes import ExtensionDtype
|
20 | 26 | from pandas.core.dtypes.generic import (
|
21 | 27 | ABCCategoricalIndex,
|
| 28 | + ABCExtensionArray, |
22 | 29 | ABCSeries,
|
23 | 30 | )
|
24 | 31 |
|
25 |
| -from pandas.core.arrays import ExtensionArray |
26 |
| -from pandas.core.arrays.sparse import SparseArray |
27 |
| -from pandas.core.construction import ( |
28 |
| - array as pd_array, |
29 |
| - ensure_wrapped_if_datetimelike, |
30 |
| -) |
| 32 | +if TYPE_CHECKING: |
| 33 | + from pandas.core.arrays.sparse import SparseArray |
31 | 34 |
|
32 | 35 |
|
33 | 36 | def cast_to_common_type(arr: ArrayLike, dtype: DtypeObj) -> ArrayLike:
|
@@ -59,26 +62,11 @@ def cast_to_common_type(arr: ArrayLike, dtype: DtypeObj) -> ArrayLike:
|
59 | 62 | # SupportsDType[dtype[Any]], str, Union[Tuple[Any, int], Tuple[Any,
|
60 | 63 | # Union[SupportsIndex, Sequence[SupportsIndex]]], List[Any], _DTypeDict,
|
61 | 64 | # Tuple[Any, Any]]]" [arg-type]
|
62 |
| - arr = cast(SparseArray, arr) |
| 65 | + arr = cast("SparseArray", arr) |
63 | 66 | return arr.to_dense().astype(dtype, copy=False) # type: ignore[arg-type]
|
64 | 67 |
|
65 |
| - if ( |
66 |
| - isinstance(arr, np.ndarray) |
67 |
| - and arr.dtype.kind in ["m", "M"] |
68 |
| - and dtype is np.dtype("object") |
69 |
| - ): |
70 |
| - # wrap datetime-likes in EA to ensure astype(object) gives Timestamp/Timedelta |
71 |
| - # this can happen when concat_compat is called directly on arrays (when arrays |
72 |
| - # are not coming from Index/Series._values), eg in BlockManager.quantile |
73 |
| - arr = ensure_wrapped_if_datetimelike(arr) |
74 |
| - |
75 |
| - if isinstance(dtype, ExtensionDtype): |
76 |
| - if isinstance(arr, np.ndarray): |
77 |
| - # numpy's astype cannot handle ExtensionDtypes |
78 |
| - return pd_array(arr, dtype=dtype, copy=False) |
79 |
| - return arr.astype(dtype, copy=False) |
80 |
| - |
81 |
| - return arr.astype(dtype, copy=False) |
| 68 | + # astype_array includes ensure_wrapped_if_datetimelike |
| 69 | + return astype_array(arr, dtype=dtype, copy=False) |
82 | 70 |
|
83 | 71 |
|
84 | 72 | def concat_compat(to_concat, axis: int = 0, ea_compat_axis: bool = False):
|
@@ -135,7 +123,8 @@ def is_nonempty(x) -> bool:
|
135 | 123 | target_dtype = find_common_type([x.dtype for x in to_concat])
|
136 | 124 | to_concat = [cast_to_common_type(arr, target_dtype) for arr in to_concat]
|
137 | 125 |
|
138 |
| - if isinstance(to_concat[0], ExtensionArray): |
| 126 | + if isinstance(to_concat[0], ABCExtensionArray): |
| 127 | + # TODO: what about EA-backed Index? |
139 | 128 | cls = type(to_concat[0])
|
140 | 129 | return cls._concat_same_type(to_concat)
|
141 | 130 | else:
|
@@ -346,6 +335,8 @@ def _concat_datetime(to_concat, axis=0):
|
346 | 335 | -------
|
347 | 336 | a single array, preserving the combined dtypes
|
348 | 337 | """
|
| 338 | + from pandas.core.construction import ensure_wrapped_if_datetimelike |
| 339 | + |
349 | 340 | to_concat = [ensure_wrapped_if_datetimelike(x) for x in to_concat]
|
350 | 341 |
|
351 | 342 | single_dtype = len({x.dtype for x in to_concat}) == 1
|
|
0 commit comments