44
44
ensure_platform_int ,
45
45
is_bool_dtype ,
46
46
is_categorical_dtype ,
47
- is_datetime64_any_dtype ,
48
47
is_dtype_equal ,
48
+ is_ea_or_datetimelike_dtype ,
49
49
is_extension_array_dtype ,
50
50
is_float ,
51
51
is_float_dtype ,
56
56
is_iterator ,
57
57
is_list_like ,
58
58
is_object_dtype ,
59
- is_period_dtype ,
60
59
is_scalar ,
61
60
is_signed_integer_dtype ,
62
- is_timedelta64_dtype ,
63
61
is_unsigned_integer_dtype ,
64
62
needs_i8_conversion ,
65
63
pandas_dtype ,
69
67
from pandas .core .dtypes .dtypes import (
70
68
CategoricalDtype ,
71
69
DatetimeTZDtype ,
70
+ ExtensionDtype ,
72
71
IntervalDtype ,
73
72
PeriodDtype ,
74
73
)
87
86
import pandas .core .algorithms as algos
88
87
from pandas .core .arrays import Categorical , ExtensionArray
89
88
from pandas .core .arrays .datetimes import tz_to_dtype , validate_tz_from_dtype
89
+ from pandas .core .arrays .sparse import SparseDtype
90
90
from pandas .core .base import IndexOpsMixin , PandasObject
91
91
import pandas .core .common as com
92
92
from pandas .core .construction import extract_array
@@ -286,44 +286,32 @@ def __new__(
286
286
287
287
# range
288
288
if isinstance (data , RangeIndex ):
289
- return RangeIndex (start = data , copy = copy , dtype = dtype , name = name )
289
+ result = RangeIndex (start = data , copy = copy , name = name )
290
+ if dtype is not None :
291
+ return result .astype (dtype , copy = False )
292
+ return result
290
293
elif isinstance (data , range ):
291
- return RangeIndex .from_range (data , dtype = dtype , name = name )
292
-
293
- # categorical
294
- elif is_categorical_dtype (data_dtype ) or is_categorical_dtype (dtype ):
295
- # Delay import for perf. https://github.com/pandas-dev/pandas/pull/31423
296
- from pandas .core .indexes .category import CategoricalIndex
297
-
298
- return _maybe_asobject (dtype , CategoricalIndex , data , copy , name , ** kwargs )
299
-
300
- # interval
301
- elif is_interval_dtype (data_dtype ) or is_interval_dtype (dtype ):
302
- # Delay import for perf. https://github.com/pandas-dev/pandas/pull/31423
303
- from pandas .core .indexes .interval import IntervalIndex
304
-
305
- return _maybe_asobject (dtype , IntervalIndex , data , copy , name , ** kwargs )
306
-
307
- elif is_datetime64_any_dtype (data_dtype ) or is_datetime64_any_dtype (dtype ):
308
- # Delay import for perf. https://github.com/pandas-dev/pandas/pull/31423
309
- from pandas import DatetimeIndex
310
-
311
- return _maybe_asobject (dtype , DatetimeIndex , data , copy , name , ** kwargs )
312
-
313
- elif is_timedelta64_dtype (data_dtype ) or is_timedelta64_dtype (dtype ):
314
- # Delay import for perf. https://github.com/pandas-dev/pandas/pull/31423
315
- from pandas import TimedeltaIndex
316
-
317
- return _maybe_asobject (dtype , TimedeltaIndex , data , copy , name , ** kwargs )
318
-
319
- elif is_period_dtype (data_dtype ) or is_period_dtype (dtype ):
320
- # Delay import for perf. https://github.com/pandas-dev/pandas/pull/31423
321
- from pandas import PeriodIndex
294
+ result = RangeIndex .from_range (data , name = name )
295
+ if dtype is not None :
296
+ return result .astype (dtype , copy = False )
297
+ return result
322
298
323
- return _maybe_asobject (dtype , PeriodIndex , data , copy , name , ** kwargs )
299
+ if is_ea_or_datetimelike_dtype (dtype ):
300
+ # non-EA dtype indexes have special casting logic, so we punt here
301
+ klass = cls ._dtype_to_subclass (dtype )
302
+ if klass is not Index :
303
+ return klass (data , dtype = dtype , copy = copy , name = name , ** kwargs )
304
+
305
+ if is_ea_or_datetimelike_dtype (data_dtype ):
306
+ klass = cls ._dtype_to_subclass (data_dtype )
307
+ if klass is not Index :
308
+ result = klass (data , copy = copy , name = name , ** kwargs )
309
+ if dtype is not None :
310
+ return result .astype (dtype , copy = False )
311
+ return result
324
312
325
313
# extension dtype
326
- elif is_extension_array_dtype (data_dtype ) or is_extension_array_dtype (dtype ):
314
+ if is_extension_array_dtype (data_dtype ) or is_extension_array_dtype (dtype ):
327
315
if not (dtype is None or is_object_dtype (dtype )):
328
316
# coerce to the provided dtype
329
317
ea_cls = dtype .construct_array_type ()
@@ -407,26 +395,38 @@ def _ensure_array(cls, data, dtype, copy: bool):
407
395
def _dtype_to_subclass (cls , dtype : DtypeObj ):
408
396
# Delay import for perf. https://github.com/pandas-dev/pandas/pull/31423
409
397
410
- if isinstance (dtype , DatetimeTZDtype ) or dtype == np .dtype ("M8[ns]" ):
398
+ if isinstance (dtype , ExtensionDtype ):
399
+ if isinstance (dtype , DatetimeTZDtype ):
400
+ from pandas import DatetimeIndex
401
+
402
+ return DatetimeIndex
403
+ elif isinstance (dtype , CategoricalDtype ):
404
+ from pandas import CategoricalIndex
405
+
406
+ return CategoricalIndex
407
+ elif isinstance (dtype , IntervalDtype ):
408
+ from pandas import IntervalIndex
409
+
410
+ return IntervalIndex
411
+ elif isinstance (dtype , PeriodDtype ):
412
+ from pandas import PeriodIndex
413
+
414
+ return PeriodIndex
415
+
416
+ elif isinstance (dtype , SparseDtype ):
417
+ return cls ._dtype_to_subclass (dtype .subtype )
418
+
419
+ return Index
420
+
421
+ if dtype .kind == "M" :
411
422
from pandas import DatetimeIndex
412
423
413
424
return DatetimeIndex
414
- elif dtype == "m8[ns]" :
425
+
426
+ elif dtype .kind == "m" :
415
427
from pandas import TimedeltaIndex
416
428
417
429
return TimedeltaIndex
418
- elif isinstance (dtype , CategoricalDtype ):
419
- from pandas import CategoricalIndex
420
-
421
- return CategoricalIndex
422
- elif isinstance (dtype , IntervalDtype ):
423
- from pandas import IntervalIndex
424
-
425
- return IntervalIndex
426
- elif isinstance (dtype , PeriodDtype ):
427
- from pandas import PeriodIndex
428
-
429
- return PeriodIndex
430
430
431
431
elif is_float_dtype (dtype ):
432
432
from pandas import Float64Index
@@ -445,6 +445,9 @@ def _dtype_to_subclass(cls, dtype: DtypeObj):
445
445
# NB: assuming away MultiIndex
446
446
return Index
447
447
448
+ elif issubclass (dtype .type , (str , bool , np .bool_ )):
449
+ return Index
450
+
448
451
raise NotImplementedError (dtype )
449
452
450
453
"""
@@ -6253,43 +6256,6 @@ def _try_convert_to_int_array(
6253
6256
raise ValueError
6254
6257
6255
6258
6256
- def _maybe_asobject (dtype , klass , data , copy : bool , name : Label , ** kwargs ):
6257
- """
6258
- If an object dtype was specified, create the non-object Index
6259
- and then convert it to object.
6260
-
6261
- Parameters
6262
- ----------
6263
- dtype : np.dtype, ExtensionDtype, str
6264
- klass : Index subclass
6265
- data : list-like
6266
- copy : bool
6267
- name : hashable
6268
- **kwargs
6269
-
6270
- Returns
6271
- -------
6272
- Index
6273
-
6274
- Notes
6275
- -----
6276
- We assume that calling .astype(object) on this klass will make a copy.
6277
- """
6278
-
6279
- # GH#23524 passing `dtype=object` to DatetimeIndex is invalid,
6280
- # will raise in the where `data` is already tz-aware. So
6281
- # we leave it out of this step and cast to object-dtype after
6282
- # the DatetimeIndex construction.
6283
-
6284
- if is_dtype_equal (_o_dtype , dtype ):
6285
- # Note we can pass copy=False because the .astype below
6286
- # will always make a copy
6287
- index = klass (data , copy = False , name = name , ** kwargs )
6288
- return index .astype (object )
6289
-
6290
- return klass (data , dtype = dtype , copy = copy , name = name , ** kwargs )
6291
-
6292
-
6293
6259
def get_unanimous_names (* indexes : Index ) -> Tuple [Label , ...]:
6294
6260
"""
6295
6261
Return common name if all indices agree, otherwise None (level-by-level).
0 commit comments