|
29 | 29 | is_hashable,
|
30 | 30 | is_iterator,
|
31 | 31 | is_dict_like,
|
| 32 | + is_dtype_equal, |
32 | 33 | is_scalar,
|
33 | 34 | _is_unorderable_exception,
|
34 | 35 | _ensure_platform_int,
|
35 |
| - pandas_dtype) |
| 36 | + pandas_dtype, |
| 37 | + needs_i8_conversion) |
36 | 38 | from pandas.core.dtypes.generic import (
|
37 | 39 | ABCSparseArray, ABCDataFrame, ABCIndexClass)
|
38 | 40 | from pandas.core.dtypes.cast import (
|
| 41 | + find_common_type, maybe_downcast_to_dtype, |
39 | 42 | maybe_upcast, infer_dtype_from_scalar,
|
40 | 43 | maybe_convert_platform,
|
41 | 44 | maybe_cast_to_datetime, maybe_castable,
|
@@ -2304,13 +2307,25 @@ def combine_first(self, other):
|
2304 | 2307 | other = other.reindex(new_index, copy=False)
|
2305 | 2308 | # TODO: do we need name?
|
2306 | 2309 | name = ops.get_op_result_name(self, other) # noqa
|
2307 |
| - rs_vals = com._where_compat(isna(this), other._values, this._values) |
2308 |
| - result = self._constructor(rs_vals, index=new_index).__finalize__(self) |
2309 |
| - # TODO DK can we simplify this using internals rather than public |
2310 |
| - # astype |
2311 |
| - if is_datetime64tz_dtype(self.dtype): |
2312 |
| - result = result.astype(self.dtype) |
2313 |
| - return result |
| 2310 | + if not is_dtype_equal(this.dtype, other.dtype): |
| 2311 | + new_dtype = find_common_type([this.dtype, other.dtype]) |
| 2312 | + if not is_dtype_equal(this.dtype, new_dtype): |
| 2313 | + this = this.astype(new_dtype) |
| 2314 | + if not is_dtype_equal(other.dtype, new_dtype): |
| 2315 | + other = other.astype(new_dtype) |
| 2316 | + |
| 2317 | + if needs_i8_conversion(this.dtype): |
| 2318 | + mask = isna(this) |
| 2319 | + this_values = this.values.view('i8') |
| 2320 | + other_values = other.values.view('i8') |
| 2321 | + else: |
| 2322 | + this_values = this.values |
| 2323 | + other_values = other.values |
| 2324 | + mask = isna(this_values) |
| 2325 | + |
| 2326 | + rs_vals = np.where(mask, other_values, this_values) |
| 2327 | + rs_vals = maybe_downcast_to_dtype(rs_vals, this.dtype) |
| 2328 | + return self._constructor(rs_vals, index=new_index).__finalize__(self) |
2314 | 2329 |
|
2315 | 2330 | def update(self, other):
|
2316 | 2331 | """
|
|
0 commit comments