|
7 | 7 |
|
8 | 8 | from __future__ import annotations
|
9 | 9 |
|
10 |
| -from collections.abc import Sequence |
11 | 10 | from typing import (
|
12 | 11 | TYPE_CHECKING,
|
13 |
| - Optional, |
14 |
| - Union, |
15 | 12 | cast,
|
16 | 13 | overload,
|
17 | 14 | )
|
|
23 | 20 |
|
24 | 21 | from pandas._libs import lib
|
25 | 22 | from pandas._libs.tslibs import (
|
26 |
| - Period, |
27 | 23 | get_supported_dtype,
|
28 | 24 | is_supported_dtype,
|
29 | 25 | )
|
30 |
| -from pandas._typing import ( |
31 |
| - AnyArrayLike, |
32 |
| - ArrayLike, |
33 |
| - Dtype, |
34 |
| - DtypeObj, |
35 |
| - T, |
36 |
| -) |
37 | 26 |
|
38 | 27 | from pandas.core.dtypes.base import ExtensionDtype
|
39 | 28 | from pandas.core.dtypes.cast import (
|
|
46 | 35 | maybe_promote,
|
47 | 36 | )
|
48 | 37 | from pandas.core.dtypes.common import (
|
| 38 | + ensure_object, |
49 | 39 | is_list_like,
|
50 | 40 | is_object_dtype,
|
51 | 41 | is_string_dtype,
|
|
63 | 53 | import pandas.core.common as com
|
64 | 54 |
|
65 | 55 | if TYPE_CHECKING:
|
| 56 | + from collections.abc import Sequence |
| 57 | + |
| 58 | + from pandas._typing import ( |
| 59 | + AnyArrayLike, |
| 60 | + ArrayLike, |
| 61 | + Dtype, |
| 62 | + DtypeObj, |
| 63 | + T, |
| 64 | + ) |
| 65 | + |
66 | 66 | from pandas import (
|
67 | 67 | Index,
|
68 | 68 | Series,
|
69 | 69 | )
|
70 |
| - from pandas.core.arrays.base import ExtensionArray |
| 70 | + from pandas.core.arrays import ( |
| 71 | + DatetimeArray, |
| 72 | + ExtensionArray, |
| 73 | + TimedeltaArray, |
| 74 | + ) |
71 | 75 |
|
72 | 76 |
|
73 | 77 | def array(
|
@@ -286,9 +290,7 @@ def array(
|
286 | 290 | ExtensionArray,
|
287 | 291 | FloatingArray,
|
288 | 292 | IntegerArray,
|
289 |
| - IntervalArray, |
290 | 293 | NumpyExtensionArray,
|
291 |
| - PeriodArray, |
292 | 294 | TimedeltaArray,
|
293 | 295 | )
|
294 | 296 | from pandas.core.arrays.string_ import StringDtype
|
@@ -320,46 +322,58 @@ def array(
|
320 | 322 | return cls._from_sequence(data, dtype=dtype, copy=copy)
|
321 | 323 |
|
322 | 324 | if dtype is None:
|
323 |
| - inferred_dtype = lib.infer_dtype(data, skipna=True) |
324 |
| - if inferred_dtype == "period": |
325 |
| - period_data = cast(Union[Sequence[Optional[Period]], AnyArrayLike], data) |
326 |
| - return PeriodArray._from_sequence(period_data, copy=copy) |
327 |
| - |
328 |
| - elif inferred_dtype == "interval": |
329 |
| - return IntervalArray(data, copy=copy) |
330 |
| - |
331 |
| - elif inferred_dtype.startswith("datetime"): |
332 |
| - # datetime, datetime64 |
333 |
| - try: |
334 |
| - return DatetimeArray._from_sequence(data, copy=copy) |
335 |
| - except ValueError: |
336 |
| - # Mixture of timezones, fall back to NumpyExtensionArray |
337 |
| - pass |
338 |
| - |
339 |
| - elif inferred_dtype.startswith("timedelta"): |
340 |
| - # timedelta, timedelta64 |
341 |
| - return TimedeltaArray._from_sequence(data, copy=copy) |
342 |
| - |
343 |
| - elif inferred_dtype == "string": |
| 325 | + was_ndarray = isinstance(data, np.ndarray) |
| 326 | + # error: Item "Sequence[object]" of "Sequence[object] | ExtensionArray | |
| 327 | + # ndarray[Any, Any]" has no attribute "dtype" |
| 328 | + if not was_ndarray or data.dtype == object: # type: ignore[union-attr] |
| 329 | + result = lib.maybe_convert_objects( |
| 330 | + ensure_object(data), |
| 331 | + convert_non_numeric=True, |
| 332 | + convert_to_nullable_dtype=True, |
| 333 | + dtype_if_all_nat=None, |
| 334 | + ) |
| 335 | + result = ensure_wrapped_if_datetimelike(result) |
| 336 | + if isinstance(result, np.ndarray): |
| 337 | + if len(result) == 0 and not was_ndarray: |
| 338 | + # e.g. empty list |
| 339 | + return FloatingArray._from_sequence(data, dtype="Float64") |
| 340 | + return NumpyExtensionArray._from_sequence( |
| 341 | + data, dtype=result.dtype, copy=copy |
| 342 | + ) |
| 343 | + if result is data and copy: |
| 344 | + return result.copy() |
| 345 | + return result |
| 346 | + |
| 347 | + data = cast(np.ndarray, data) |
| 348 | + result = ensure_wrapped_if_datetimelike(data) |
| 349 | + if result is not data: |
| 350 | + result = cast("DatetimeArray | TimedeltaArray", result) |
| 351 | + if copy and result.dtype == data.dtype: |
| 352 | + return result.copy() |
| 353 | + return result |
| 354 | + |
| 355 | + if data.dtype.kind in "SU": |
344 | 356 | # StringArray/ArrowStringArray depending on pd.options.mode.string_storage
|
345 | 357 | dtype = StringDtype()
|
346 | 358 | cls = dtype.construct_array_type()
|
347 | 359 | return cls._from_sequence(data, dtype=dtype, copy=copy)
|
348 | 360 |
|
349 |
| - elif inferred_dtype == "integer": |
| 361 | + elif data.dtype.kind in "iu": |
350 | 362 | return IntegerArray._from_sequence(data, copy=copy)
|
351 |
| - elif inferred_dtype == "empty" and not hasattr(data, "dtype") and not len(data): |
352 |
| - return FloatingArray._from_sequence(data, copy=copy) |
353 |
| - elif ( |
354 |
| - inferred_dtype in ("floating", "mixed-integer-float") |
355 |
| - and getattr(data, "dtype", None) != np.float16 |
356 |
| - ): |
| 363 | + elif data.dtype.kind == "f": |
357 | 364 | # GH#44715 Exclude np.float16 bc FloatingArray does not support it;
|
358 | 365 | # we will fall back to NumpyExtensionArray.
|
| 366 | + if data.dtype == np.float16: |
| 367 | + return NumpyExtensionArray._from_sequence( |
| 368 | + data, dtype=data.dtype, copy=copy |
| 369 | + ) |
359 | 370 | return FloatingArray._from_sequence(data, copy=copy)
|
360 | 371 |
|
361 |
| - elif inferred_dtype == "boolean": |
| 372 | + elif data.dtype.kind == "b": |
362 | 373 | return BooleanArray._from_sequence(data, dtype="boolean", copy=copy)
|
| 374 | + else: |
| 375 | + # e.g. complex |
| 376 | + return NumpyExtensionArray._from_sequence(data, dtype=data.dtype, copy=copy) |
363 | 377 |
|
364 | 378 | # Pandas overrides NumPy for
|
365 | 379 | # 1. datetime64[ns,us,ms,s]
|
|
0 commit comments