@@ -1081,12 +1081,23 @@ def _infer_dtype_from_scalar(val):
1081
1081
return dtype , val
1082
1082
1083
1083
1084
- def _maybe_cast_scalar (dtype , value ):
1085
- """ if we a scalar value and are casting to a dtype that needs nan -> NaT
1086
- conversion
1084
+ def _maybe_cast (dtype , value ):
1087
1085
"""
1088
- if np .isscalar (value ) and dtype in _DATELIKE_DTYPES and isnull (value ):
1089
- return tslib .iNaT
1086
+ If `dtype` is date-like, then:
1087
+ if `value` == nan, then convert to NaT
1088
+ if `value` is an integer or integer array, convert to `dtype`
1089
+ """
1090
+ if dtype in _DATELIKE_DTYPES :
1091
+ if np .isscalar (value ):
1092
+ if isnull (value ):
1093
+ return tslib .iNaT
1094
+ elif is_integer (value ):
1095
+ return np .array (value , dtype = dtype )
1096
+
1097
+ elif isinstance (value , np .ndarray ):
1098
+ if issubclass (dtype .type , np .integer ):
1099
+ return np .array (value , dtype = dtype )
1100
+
1090
1101
return value
1091
1102
1092
1103
@@ -1154,16 +1165,29 @@ def _maybe_promote(dtype, fill_value=np.nan):
1154
1165
return dtype , fill_value
1155
1166
1156
1167
1157
- def _maybe_upcast_putmask (result , mask , other , dtype = None , change = None ):
1158
- """ a safe version of put mask that (potentially upcasts the result
1159
- return the result
1160
- if change is not None, then MUTATE the change (and change the dtype)
1161
- return a changed flag
1168
+ def _maybe_upcast_putmask (result , mask , other ):
1169
+ """
1170
+ A safe version of putmask that potentially upcasts the result
1171
+
1172
+ Parameters
1173
+ ----------
1174
+ result : ndarray
1175
+ The destination array. This will be mutated in-place if no upcasting is
1176
+ necessary.
1177
+ mask : boolean ndarray
1178
+ other : ndarray or scalar
1179
+ The source array or value
1180
+
1181
+ Returns
1182
+ -------
1183
+ result : ndarray
1184
+ changed : boolean
1185
+ Set to true if the result array was upcasted
1162
1186
"""
1163
1187
1164
1188
if mask .any ():
1165
1189
1166
- other = _maybe_cast_scalar (result .dtype , other )
1190
+ other = _maybe_cast (result .dtype , other )
1167
1191
1168
1192
def changeit ():
1169
1193
@@ -1173,39 +1197,26 @@ def changeit():
1173
1197
om = other [mask ]
1174
1198
om_at = om .astype (result .dtype )
1175
1199
if (om == om_at ).all ():
1176
- new_other = result .values .copy ()
1177
- new_other [mask ] = om_at
1178
- result [:] = new_other
1200
+ new_result = result .values .copy ()
1201
+ new_result [mask ] = om_at
1202
+ result [:] = new_result
1179
1203
return result , False
1180
1204
except :
1181
1205
pass
1182
1206
1183
1207
# we are forced to change the dtype of the result as the input
1184
1208
# isn't compatible
1185
- r , fill_value = _maybe_upcast (
1186
- result , fill_value = other , dtype = dtype , copy = True )
1187
- np .putmask (r , mask , other )
1188
-
1189
- # we need to actually change the dtype here
1190
- if change is not None :
1191
-
1192
- # if we are trying to do something unsafe
1193
- # like put a bigger dtype in a smaller one, use the smaller one
1194
- # pragma: no cover
1195
- if change .dtype .itemsize < r .dtype .itemsize :
1196
- raise AssertionError (
1197
- "cannot change dtype of input to smaller size" )
1198
- change .dtype = r .dtype
1199
- change [:] = r
1209
+ r , _ = _maybe_upcast (result , fill_value = other , copy = True )
1210
+ np .place (r , mask , other )
1200
1211
1201
1212
return r , True
1202
1213
1203
- # we want to decide whether putmask will work
1214
+ # we want to decide whether place will work
1204
1215
# if we have nans in the False portion of our mask then we need to
1205
- # upcast (possibily) otherwise we DON't want to upcast (e.g. if we are
1206
- # have values, say integers in the success portion then its ok to not
1216
+ # upcast (possibly), otherwise we DON't want to upcast (e.g. if we
1217
+ # have values, say integers, in the success portion then it's ok to not
1207
1218
# upcast)
1208
- new_dtype , fill_value = _maybe_promote (result .dtype , other )
1219
+ new_dtype , _ = _maybe_promote (result .dtype , other )
1209
1220
if new_dtype != result .dtype :
1210
1221
1211
1222
# we have a scalar or len 0 ndarray
@@ -1222,7 +1233,7 @@ def changeit():
1222
1233
return changeit ()
1223
1234
1224
1235
try :
1225
- np .putmask (result , mask , other )
1236
+ np .place (result , mask , other )
1226
1237
except :
1227
1238
return changeit ()
1228
1239
0 commit comments