@@ -41,6 +41,7 @@ from pandas._libs.tslibs.conversion cimport (
41
41
cast_from_unit,
42
42
convert_datetime_to_tsobject,
43
43
get_datetime64_nanos,
44
+ precision_from_unit,
44
45
)
45
46
from pandas._libs.tslibs.nattype cimport (
46
47
NPY_NAT,
@@ -205,6 +206,7 @@ def array_with_unit_to_datetime(
205
206
cdef:
206
207
Py_ssize_t i, j, n= len (values)
207
208
int64_t m
209
+ int prec = 0
208
210
ndarray[float64_t] fvalues
209
211
bint is_ignore = errors== ' ignore'
210
212
bint is_coerce = errors== ' coerce'
@@ -217,38 +219,48 @@ def array_with_unit_to_datetime(
217
219
218
220
assert is_ignore or is_coerce or is_raise
219
221
220
- if unit == ' ns ' :
221
- if issubclass (values.dtype.type, np.integer):
222
- result = values.astype(' M8[ns]' )
222
+ if unit == " ns " :
223
+ if issubclass (values.dtype.type, ( np.integer, np.float_) ):
224
+ result = values.astype(" M8[ns]" , copy = False )
223
225
else :
224
226
result, tz = array_to_datetime(values.astype(object ), errors = errors)
225
227
return result, tz
226
228
227
- m = cast_from_unit( None , unit)
229
+ m, p = precision_from_unit( unit)
228
230
229
231
if is_raise:
230
-
231
- # try a quick conversion to i8
232
+ # try a quick conversion to i8/f8
232
233
# if we have nulls that are not type-compat
233
234
# then need to iterate
234
- if values.dtype.kind == " i " :
235
- # Note: this condition makes the casting="same_kind" redundant
236
- iresult = values.astype(' i8 ' , casting = ' same_kind ' , copy = False )
237
- # fill by comparing to NPY_NAT constant
235
+
236
+ if values.dtype.kind == " i " or values.dtype.kind == " f " :
237
+ iresult = values.astype(" i8 " , copy = False )
238
+ # fill missing values by comparing to NPY_NAT
238
239
mask = iresult == NPY_NAT
239
240
iresult[mask] = 0
240
- fvalues = iresult.astype(' f8 ' ) * m
241
+ fvalues = iresult.astype(" f8 " ) * m
241
242
need_to_iterate = False
242
243
243
- # check the bounds
244
244
if not need_to_iterate:
245
-
246
- if ((fvalues < Timestamp.min.value).any()
247
- or (fvalues > Timestamp.max.value).any()):
245
+ # check the bounds
246
+ if (fvalues < Timestamp.min.value).any() or (
247
+ (fvalues > Timestamp.max.value).any()
248
+ ):
248
249
raise OutOfBoundsDatetime(f" cannot convert input with unit '{unit}'" )
249
- result = (iresult * m).astype(' M8[ns]' )
250
- iresult = result.view(' i8' )
250
+
251
+ if values.dtype.kind == " i" :
252
+ result = (iresult * m).astype(" M8[ns]" )
253
+
254
+ elif values.dtype.kind == " f" :
255
+ fresult = (values * m).astype(" f8" )
256
+ fresult[mask] = 0
257
+ if prec:
258
+ fresult = round (fresult, prec)
259
+ result = fresult.astype(" M8[ns]" , copy = False )
260
+
261
+ iresult = result.view(" i8" )
251
262
iresult[mask] = NPY_NAT
263
+
252
264
return result, tz
253
265
254
266
result = np.empty(n, dtype = ' M8[ns]' )
0 commit comments