@@ -439,31 +439,87 @@ def infer_dtype(object value):
439
439
return ' mixed'
440
440
441
441
442
- cpdef bint is_possible_datetimelike_array(object arr):
443
- # determine if we have a possible datetimelike (or null-like) array
442
+ cpdef object infer_datetimelike_array(object arr):
443
+ """
444
+ infer if we have a datetime or timedelta array
445
+ - date: we have *only* date and myabe strings, nulls
446
+ - datetime: we have *only* datetimes and maybe strings, nulls
447
+ - timedelta: we have *only* timedeltas and maybe strings, nulls
448
+ - nat: we do not have *any* date, datetimes or timedeltas, but do have
449
+ at least a NaT
450
+ - mixed: other objects (strings or actual objects)
451
+
452
+ Parameters
453
+ ----------
454
+ arr : object array
455
+
456
+ Returns
457
+ -------
458
+ string: {datetime, timedelta, date, nat, mixed}
459
+
460
+ """
461
+
444
462
cdef:
445
463
Py_ssize_t i, n = len (arr)
446
- bint seen_timedelta = 0 , seen_datetime = 0
464
+ bint seen_timedelta = 0 , seen_date = 0 , seen_datetime = 0
465
+ bint seen_nat = 0
466
+ list objs = []
447
467
object v
448
468
449
469
for i in range (n):
450
470
v = arr[i]
451
471
if util.is_string_object(v):
452
- continue
472
+ objs.append(v)
473
+
474
+ if len (objs) == 3 :
475
+ break
476
+
453
477
elif util._checknull(v):
454
- continue
455
- elif is_datetime(v):
456
- seen_datetime= 1
457
- elif is_timedelta(v):
458
- seen_timedelta= 1
478
+ # nan or None
479
+ seen_null = 1
480
+ elif v is NaT:
481
+ seen_nat = 1
482
+ elif is_datetime(v) or util.is_datetime64_object(v):
483
+ # datetime, or np.datetime64
484
+ seen_datetime = 1
485
+ elif is_date(v):
486
+ seen_date = 1
487
+ elif is_timedelta(v) or util.is_timedelta64_object(v):
488
+ # timedelta, or timedelta64
489
+ seen_timedelta = 1
459
490
else :
460
- return False
461
- return seen_datetime or seen_timedelta
491
+ return ' mixed'
492
+
493
+ if seen_date and not (seen_datetime or seen_timedelta):
494
+ return ' date'
495
+ elif seen_datetime and not seen_timedelta:
496
+ return ' datetime'
497
+ elif seen_timedelta and not seen_datetime:
498
+ return ' timedelta'
499
+ elif seen_nat:
500
+ return ' nat'
501
+
502
+ # short-circuit by trying to
503
+ # actually convert these strings
504
+ # this is for performance as we don't need to try
505
+ # convert *every* string array
506
+ if len (objs) == 3 :
507
+ try :
508
+ tslib.array_to_datetime(objs, errors = ' raise' )
509
+ return ' datetime'
510
+ except :
511
+ pass
512
+
513
+ # we are *not* going to infer from strings
514
+ # for timedelta as too much ambiguity
515
+
516
+ return ' mixed'
517
+
462
518
463
519
464
520
cdef inline bint is_null_datetimelike(v):
465
521
# determine if we have a null for a timedelta/datetime (or integer
466
- # versions)x
522
+ # versions)
467
523
if util._checknull(v):
468
524
return True
469
525
elif v is NaT:
0 commit comments