Skip to content

Commit eda7592

Browse files
authored
BUG: maybe_promote with dt64tz and mismatched NA (#39743)
1 parent 5a35050 commit eda7592

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

pandas/core/dtypes/cast.py

+22-21
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
import numpy as np
2626

27-
from pandas._libs import lib, missing as libmissing, tslib
27+
from pandas._libs import lib, tslib
2828
from pandas._libs.tslibs import (
2929
NaT,
3030
OutOfBoundsDatetime,
@@ -86,7 +86,12 @@
8686
ABCSeries,
8787
)
8888
from pandas.core.dtypes.inference import is_list_like
89-
from pandas.core.dtypes.missing import is_valid_na_for_dtype, isna, notna
89+
from pandas.core.dtypes.missing import (
90+
is_valid_na_for_dtype,
91+
isna,
92+
na_value_for_dtype,
93+
notna,
94+
)
9095

9196
if TYPE_CHECKING:
9297
from pandas import Series
@@ -529,16 +534,26 @@ def maybe_promote(dtype: np.dtype, fill_value=np.nan):
529534
dtype = np.dtype(object)
530535
return dtype, fill_value
531536

537+
kinds = ["i", "u", "f", "c", "m", "M"]
538+
if is_valid_na_for_dtype(fill_value, dtype) and dtype.kind in kinds:
539+
dtype = ensure_dtype_can_hold_na(dtype)
540+
fv = na_value_for_dtype(dtype)
541+
return dtype, fv
542+
543+
elif isna(fill_value):
544+
dtype = np.dtype(object)
545+
if fill_value is None:
546+
# but we retain e.g. pd.NA
547+
fill_value = np.nan
548+
return dtype, fill_value
549+
532550
# returns tuple of (dtype, fill_value)
533551
if issubclass(dtype.type, np.datetime64):
534552
if isinstance(fill_value, datetime) and fill_value.tzinfo is not None:
535553
# Trying to insert tzaware into tznaive, have to cast to object
536554
dtype = np.dtype(np.object_)
537-
elif is_integer(fill_value) or (is_float(fill_value) and not isna(fill_value)):
555+
elif is_integer(fill_value) or is_float(fill_value):
538556
dtype = np.dtype(np.object_)
539-
elif is_valid_na_for_dtype(fill_value, dtype):
540-
# e.g. pd.NA, which is not accepted by Timestamp constructor
541-
fill_value = np.datetime64("NaT", "ns")
542557
else:
543558
try:
544559
fill_value = Timestamp(fill_value).to_datetime64()
@@ -547,14 +562,11 @@ def maybe_promote(dtype: np.dtype, fill_value=np.nan):
547562
elif issubclass(dtype.type, np.timedelta64):
548563
if (
549564
is_integer(fill_value)
550-
or (is_float(fill_value) and not np.isnan(fill_value))
565+
or is_float(fill_value)
551566
or isinstance(fill_value, str)
552567
):
553568
# TODO: What about str that can be a timedelta?
554569
dtype = np.dtype(np.object_)
555-
elif is_valid_na_for_dtype(fill_value, dtype):
556-
# e.g pd.NA, which is not accepted by the Timedelta constructor
557-
fill_value = np.timedelta64("NaT", "ns")
558570
else:
559571
try:
560572
fv = Timedelta(fill_value)
@@ -615,17 +627,6 @@ def maybe_promote(dtype: np.dtype, fill_value=np.nan):
615627
# e.g. mst is np.complex128 and dtype is np.complex64
616628
dtype = mst
617629

618-
elif fill_value is None or fill_value is libmissing.NA:
619-
# Note: we already excluded dt64/td64 dtypes above
620-
if is_float_dtype(dtype) or is_complex_dtype(dtype):
621-
fill_value = np.nan
622-
elif is_integer_dtype(dtype):
623-
dtype = np.dtype(np.float64)
624-
fill_value = np.nan
625-
else:
626-
dtype = np.dtype(np.object_)
627-
if fill_value is not libmissing.NA:
628-
fill_value = np.nan
629630
else:
630631
dtype = np.dtype(np.object_)
631632

0 commit comments

Comments
 (0)