2424
2525import numpy as np
2626
27- from pandas ._libs import lib , missing as libmissing , tslib
27+ from pandas ._libs import lib , tslib
2828from pandas ._libs .tslibs import (
2929 NaT ,
3030 OutOfBoundsDatetime ,
8686 ABCSeries ,
8787)
8888from 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
9196if 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