1
1
from collections import abc
2
2
from datetime import datetime , time
3
3
from functools import partial
4
+ from typing import Optional , TypeVar , Union
4
5
5
6
import numpy as np
6
7
14
15
from pandas .core .dtypes .common import (
15
16
ensure_object , is_datetime64_dtype , is_datetime64_ns_dtype ,
16
17
is_datetime64tz_dtype , is_float , is_integer , is_integer_dtype ,
17
- is_list_like , is_numeric_dtype , is_object_dtype , is_scalar )
18
- from pandas .core .dtypes .generic import ABCDataFrame , ABCIndexClass , ABCSeries
18
+ is_list_like , is_numeric_dtype , is_scalar )
19
+ from pandas .core .dtypes .generic import (
20
+ ABCDataFrame , ABCDatetimeIndex , ABCIndex , ABCIndexClass , ABCSeries )
19
21
from pandas .core .dtypes .missing import notna
20
22
23
+ from pandas ._typing import ArrayLike
21
24
from pandas .core import algorithms
22
25
26
+ # ---------------------------------------------------------------------
27
+ # types used in annotations
28
+
29
+ Scalar = Union [int , float , str ]
30
+ DatetimeScalar = TypeVar ('DatetimeScalar' , Scalar , datetime )
31
+ DatetimeScalarOrArrayConvertible = Union [DatetimeScalar , list , tuple ,
32
+ ArrayLike , ABCSeries ]
33
+
34
+
35
+ # ---------------------------------------------------------------------
36
+
23
37
24
38
def _guess_datetime_format_for_array (arr , ** kwargs ):
25
39
# Try to guess the format based on the first non-NaN element
@@ -60,7 +74,43 @@ def _maybe_cache(arg, format, cache, convert_listlike):
60
74
return cache_array
61
75
62
76
63
- def _convert_and_box_cache (arg , cache_array , box , errors , name = None ):
77
+ def _box_as_indexlike (
78
+ dt_array : ArrayLike ,
79
+ utc : Optional [bool ] = None ,
80
+ name : Optional [str ] = None
81
+ ) -> Union [ABCIndex , ABCDatetimeIndex ]:
82
+ """
83
+ Properly boxes the ndarray of datetimes to DatetimeIndex
84
+ if it is possible or to generic Index instead
85
+
86
+ Parameters
87
+ ----------
88
+ dt_array: 1-d array
89
+ array of datetimes to be boxed
90
+ tz : object
91
+ None or 'utc'
92
+ name : string, default None
93
+ Name for a resulting index
94
+
95
+ Returns
96
+ -------
97
+ result : datetime of converted dates
98
+ - DatetimeIndex if convertible to sole datetime64 type
99
+ - general Index otherwise
100
+ """
101
+ from pandas import DatetimeIndex , Index
102
+ if is_datetime64_dtype (dt_array ):
103
+ tz = 'utc' if utc else None
104
+ return DatetimeIndex (dt_array , tz = tz , name = name )
105
+ return Index (dt_array , name = name )
106
+
107
+
108
+ def _convert_and_box_cache (
109
+ arg : DatetimeScalarOrArrayConvertible ,
110
+ cache_array : ABCSeries ,
111
+ box : bool ,
112
+ name : Optional [str ] = None
113
+ ) -> Union [ABCIndex , np .ndarray ]:
64
114
"""
65
115
Convert array of dates with a cache and box the result
66
116
@@ -71,26 +121,19 @@ def _convert_and_box_cache(arg, cache_array, box, errors, name=None):
71
121
Cache of converted, unique dates
72
122
box : boolean
73
123
True boxes result as an Index-like, False returns an ndarray
74
- errors : string
75
- 'ignore' plus box=True will convert result to Index
76
124
name : string, default None
77
125
Name for a DatetimeIndex
78
126
79
127
Returns
80
128
-------
81
129
result : datetime of converted dates
82
- Returns:
83
-
84
130
- Index-like if box=True
85
131
- ndarray if box=False
86
132
"""
87
- from pandas import Series , DatetimeIndex , Index
133
+ from pandas import Series
88
134
result = Series (arg ).map (cache_array )
89
135
if box :
90
- if errors == 'ignore' :
91
- return Index (result , name = name )
92
- else :
93
- return DatetimeIndex (result , name = name )
136
+ return _box_as_indexlike (result , utc = None , name = name )
94
137
return result .values
95
138
96
139
@@ -118,7 +161,6 @@ def _return_parsed_timezone_results(result, timezones, box, tz, name):
118
161
119
162
- Index-like if box=True
120
163
- ndarray of Timestamps if box=False
121
-
122
164
"""
123
165
if tz is not None :
124
166
raise ValueError ("Cannot pass a tz argument when "
@@ -324,13 +366,8 @@ def _convert_listlike_datetimes(arg, box, format, name=None, tz=None,
324
366
return np .array (result , dtype = object )
325
367
326
368
if box :
327
- # Ensure we return an Index in all cases where box=True
328
- if is_datetime64_dtype (result ):
329
- return DatetimeIndex (result , tz = tz , name = name )
330
- elif is_object_dtype (result ):
331
- # e.g. an Index of datetime objects
332
- from pandas import Index
333
- return Index (result , name = name )
369
+ utc = tz == 'utc'
370
+ return _box_as_indexlike (result , utc = utc , name = name )
334
371
return result
335
372
336
373
@@ -611,15 +648,15 @@ def to_datetime(arg, errors='raise', dayfirst=False, yearfirst=False,
611
648
elif isinstance (arg , ABCIndexClass ):
612
649
cache_array = _maybe_cache (arg , format , cache , convert_listlike )
613
650
if not cache_array .empty :
614
- result = _convert_and_box_cache (arg , cache_array , box , errors ,
651
+ result = _convert_and_box_cache (arg , cache_array , box ,
615
652
name = arg .name )
616
653
else :
617
654
convert_listlike = partial (convert_listlike , name = arg .name )
618
655
result = convert_listlike (arg , box , format )
619
656
elif is_list_like (arg ):
620
657
cache_array = _maybe_cache (arg , format , cache , convert_listlike )
621
658
if not cache_array .empty :
622
- result = _convert_and_box_cache (arg , cache_array , box , errors )
659
+ result = _convert_and_box_cache (arg , cache_array , box )
623
660
else :
624
661
result = convert_listlike (arg , box , format )
625
662
else :
0 commit comments