@@ -3738,8 +3738,11 @@ def combine(self, other, func, fill_value=None, overwrite=True):
3738
3738
3739
3739
result = {}
3740
3740
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
3743
3746
3744
3747
this_mask = isnull (series )
3745
3748
other_mask = isnull (otherSeries )
@@ -3756,18 +3759,40 @@ def combine(self, other, func, fill_value=None, overwrite=True):
3756
3759
series [this_mask ] = fill_value
3757
3760
otherSeries [other_mask ] = fill_value
3758
3761
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 )
3760
3777
3761
3778
if do_fill :
3762
3779
arr = com .ensure_float (arr )
3763
3780
arr [this_mask & other_mask ] = NA
3764
3781
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
+
3765
3788
result [col ] = arr
3766
3789
3767
3790
# convert_objects just in case
3768
3791
return self ._constructor (result ,
3769
3792
index = new_index ,
3770
- columns = new_columns ).convert_objects (copy = False )
3793
+ columns = new_columns ).convert_objects (
3794
+ convert_dates = True ,
3795
+ copy = False )
3771
3796
3772
3797
def combine_first (self , other ):
3773
3798
"""
@@ -3788,8 +3813,18 @@ def combine_first(self, other):
3788
3813
-------
3789
3814
combined : DataFrame
3790
3815
"""
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
+
3793
3828
return self .combine (other , combiner , overwrite = False )
3794
3829
3795
3830
def update (self , other , join = 'left' , overwrite = True , filter_func = None ,
0 commit comments