12
12
from pandas ._typing import ArrayLike , Dtype , DtypeObj , F , Scalar
13
13
from pandas .compat ._optional import import_optional_dependency
14
14
15
- from pandas .core .dtypes .cast import maybe_upcast_putmask
16
15
from pandas .core .dtypes .common import (
17
16
get_dtype ,
18
17
is_any_int_dtype ,
@@ -284,18 +283,20 @@ def _get_values(
284
283
"""
285
284
# In _get_values is only called from within nanops, and in all cases
286
285
# with scalar fill_value. This guarantee is important for the
287
- # maybe_upcast_putmask call below
286
+ # np.where call below
288
287
assert is_scalar (fill_value )
289
288
values = extract_array (values , extract_numpy = True )
290
289
291
290
mask = _maybe_get_mask (values , skipna , mask )
292
291
293
292
dtype = values .dtype
294
293
294
+ datetimelike = False
295
295
if needs_i8_conversion (values .dtype ):
296
296
# changing timedelta64/datetime64 to int64 needs to happen after
297
297
# finding `mask` above
298
298
values = np .asarray (values .view ("i8" ))
299
+ datetimelike = True
299
300
300
301
dtype_ok = _na_ok_dtype (dtype )
301
302
@@ -306,13 +307,13 @@ def _get_values(
306
307
)
307
308
308
309
if skipna and (mask is not None ) and (fill_value is not None ):
309
- values = values . copy ()
310
- if dtype_ok and mask . any () :
311
- np . putmask ( values , mask , fill_value )
312
-
313
- # promote if needed
314
- else :
315
- values , _ = maybe_upcast_putmask ( values , mask , fill_value )
310
+ if mask . any ():
311
+ if dtype_ok or datetimelike :
312
+ values = values . copy ( )
313
+ np . putmask ( values , mask , fill_value )
314
+ else :
315
+ # np.where will promote if needed
316
+ values = np . where ( ~ mask , values , fill_value )
316
317
317
318
# return a platform independent precision dtype
318
319
dtype_max = dtype
0 commit comments