@@ -3738,8 +3738,11 @@ def combine(self, other, func, fill_value=None, overwrite=True):
37383738
37393739 result = {}
37403740 for col in new_columns :
3741- series = this [col ].values
3742- otherSeries = other [col ].values
3741+ series = this [col ]
3742+ otherSeries = other [col ]
3743+
3744+ this_dtype = series .dtype
3745+ other_dtype = otherSeries .dtype
37433746
37443747 this_mask = isnull (series )
37453748 other_mask = isnull (otherSeries )
@@ -3756,18 +3759,40 @@ def combine(self, other, func, fill_value=None, overwrite=True):
37563759 series [this_mask ] = fill_value
37573760 otherSeries [other_mask ] = fill_value
37583761
3759- arr = func (series , otherSeries )
3762+ # if we have different dtypes, possibily promote
3763+ new_dtype = this_dtype
3764+ if this_dtype != other_dtype :
3765+ new_dtype = com ._lcd_dtypes (this_dtype ,other_dtype )
3766+ series = series .astype (new_dtype )
3767+ otherSeries = otherSeries .astype (new_dtype )
3768+
3769+ # see if we need to be represented as i8 (datetimelike)
3770+ # try to keep us at this dtype
3771+ needs_i8_conversion = com .needs_i8_conversion (new_dtype )
3772+ if needs_i8_conversion :
3773+ this_dtype = new_dtype
3774+ arr = func (series , otherSeries , True )
3775+ else :
3776+ arr = func (series , otherSeries )
37603777
37613778 if do_fill :
37623779 arr = com .ensure_float (arr )
37633780 arr [this_mask & other_mask ] = NA
37643781
3782+ # try to downcast back to the original dtype
3783+ if needs_i8_conversion :
3784+ arr = com ._possibly_cast_to_datetime (arr , this_dtype )
3785+ else :
3786+ arr = com ._possibly_downcast_to_dtype (arr , this_dtype )
3787+
37653788 result [col ] = arr
37663789
37673790 # convert_objects just in case
37683791 return self ._constructor (result ,
37693792 index = new_index ,
3770- columns = new_columns ).convert_objects (copy = False )
3793+ columns = new_columns ).convert_objects (
3794+ convert_dates = True ,
3795+ copy = False )
37713796
37723797 def combine_first (self , other ):
37733798 """
@@ -3788,8 +3813,18 @@ def combine_first(self, other):
37883813 -------
37893814 combined : DataFrame
37903815 """
3791- def combiner (x , y ):
3792- return expressions .where (isnull (x ), y , x , raise_on_error = True )
3816+ def combiner (x , y , needs_i8_conversion = False ):
3817+ x_values = x .values if hasattr (x ,'values' ) else x
3818+ y_values = y .values if hasattr (y ,'values' ) else y
3819+ if needs_i8_conversion :
3820+ mask = isnull (x )
3821+ x_values = x_values .view ('i8' )
3822+ y_values = y_values .view ('i8' )
3823+ else :
3824+ mask = isnull (x_values )
3825+
3826+ return expressions .where (mask , y_values , x_values , raise_on_error = True )
3827+
37933828 return self .combine (other , combiner , overwrite = False )
37943829
37953830 def update (self , other , join = 'left' , overwrite = True , filter_func = None ,
0 commit comments