@@ -43,6 +43,9 @@ class AmbiguousIndexError(PandasError, KeyError):
43
43
44
44
45
45
_POSSIBLY_CAST_DTYPES = set ([ np .dtype (t ) for t in ['M8[ns]' ,'m8[ns]' ,'O' ,'int8' ,'uint8' ,'int16' ,'uint16' ,'int32' ,'uint32' ,'int64' ,'uint64' ] ])
46
+ _NS_DTYPE = np .dtype ('M8[ns]' )
47
+ _TD_DTYPE = np .dtype ('m8[ns]' )
48
+ _INT64_DTYPE = np .dtype (np .int64 )
46
49
47
50
def isnull (obj ):
48
51
'''
@@ -1084,6 +1087,12 @@ def _possibly_cast_to_datetime(value, dtype, coerce = False):
1084
1087
1085
1088
if is_datetime64 or is_timedelta64 :
1086
1089
1090
+ # force the dtype if needed
1091
+ if is_datetime64 and dtype != _NS_DTYPE :
1092
+ raise TypeError ("cannot convert datetimelike to dtype [%s]" % dtype )
1093
+ elif is_timedelta64 and dtype != _TD_DTYPE :
1094
+ raise TypeError ("cannot convert timedeltalike to dtype [%s]" % dtype )
1095
+
1087
1096
if np .isscalar (value ):
1088
1097
if value == tslib .iNaT or isnull (value ):
1089
1098
value = tslib .iNaT
@@ -1098,7 +1107,8 @@ def _possibly_cast_to_datetime(value, dtype, coerce = False):
1098
1107
elif np .prod (value .shape ) and value .dtype != dtype :
1099
1108
try :
1100
1109
if is_datetime64 :
1101
- value = tslib .array_to_datetime (value , coerce = coerce )
1110
+ from pandas .tseries .tools import to_datetime
1111
+ value = to_datetime (value , coerce = coerce ).values
1102
1112
elif is_timedelta64 :
1103
1113
value = _possibly_cast_to_timedelta (value )
1104
1114
except :
@@ -1119,12 +1129,12 @@ def _possibly_cast_to_datetime(value, dtype, coerce = False):
1119
1129
v = [ v ]
1120
1130
if len (v ):
1121
1131
inferred_type = lib .infer_dtype (v )
1122
- if inferred_type == 'datetime' :
1132
+ if inferred_type in [ 'datetime' , 'datetime64' ] :
1123
1133
try :
1124
1134
value = tslib .array_to_datetime (np .array (v ))
1125
1135
except :
1126
1136
pass
1127
- elif inferred_type == 'timedelta' :
1137
+ elif inferred_type in [ 'timedelta' , 'timedelta64' ] :
1128
1138
value = _possibly_cast_to_timedelta (value )
1129
1139
1130
1140
return value
@@ -1515,9 +1525,24 @@ def _astype_nansafe(arr, dtype, copy = True):
1515
1525
if not isinstance (dtype , np .dtype ):
1516
1526
dtype = np .dtype (dtype )
1517
1527
1518
- if issubclass (arr . dtype . type , np . datetime64 ):
1528
+ if is_datetime64_dtype (arr ):
1519
1529
if dtype == object :
1520
1530
return tslib .ints_to_pydatetime (arr .view (np .int64 ))
1531
+ elif issubclass (dtype .type , np .int ):
1532
+ return arr .view (dtype )
1533
+ elif dtype != _NS_DTYPE :
1534
+ raise TypeError ("cannot astype a datetimelike from [%s] to [%s]" % (arr .dtype ,dtype ))
1535
+ return arr .astype (_NS_DTYPE )
1536
+ elif is_timedelta64_dtype (arr ):
1537
+ if issubclass (dtype .type , np .int ):
1538
+ return arr .view (dtype )
1539
+ elif dtype == object :
1540
+ return arr .astype (object )
1541
+
1542
+ # in py3, timedelta64[ns] are int64
1543
+ elif (py3compat .PY3 and dtype not in [_INT64_DTYPE ,_TD_DTYPE ]) or (not py3compat .PY3 and dtype != _TD_DTYPE ):
1544
+ raise TypeError ("cannot astype a timedelta from [%s] to [%s]" % (arr .dtype ,dtype ))
1545
+ return arr .astype (_TD_DTYPE )
1521
1546
elif (np .issubdtype (arr .dtype , np .floating ) and
1522
1547
np .issubdtype (dtype , np .integer )):
1523
1548
@@ -1721,9 +1746,6 @@ def _check_as_is(x):
1721
1746
self .queue .truncate (0 )
1722
1747
1723
1748
1724
- _NS_DTYPE = np .dtype ('M8[ns]' )
1725
-
1726
-
1727
1749
def _concat_compat (to_concat , axis = 0 ):
1728
1750
# filter empty arrays
1729
1751
to_concat = [x for x in to_concat if x .shape [axis ] > 0 ]
@@ -1751,7 +1773,6 @@ def _to_pydatetime(x):
1751
1773
1752
1774
return x
1753
1775
1754
-
1755
1776
def _where_compat (mask , arr1 , arr2 ):
1756
1777
if arr1 .dtype == _NS_DTYPE and arr2 .dtype == _NS_DTYPE :
1757
1778
new_vals = np .where (mask , arr1 .view (np .int64 ), arr2 .view (np .int64 ))
0 commit comments