|
7 | 7 |
|
8 | 8 | from pandas.core.dtypes.common import (
|
9 | 9 | is_bool, is_bool_dtype, is_dtype_equal, is_extension_array_dtype, is_float,
|
10 |
| - is_integer_dtype, is_scalar, needs_i8_conversion, pandas_dtype) |
| 10 | + is_float_dtype, is_integer_dtype, is_scalar, needs_i8_conversion, |
| 11 | + pandas_dtype) |
11 | 12 | import pandas.core.dtypes.concat as _concat
|
12 |
| -from pandas.core.dtypes.generic import ABCInt64Index, ABCRangeIndex |
| 13 | +from pandas.core.dtypes.generic import ( |
| 14 | + ABCFloat64Index, ABCInt64Index, ABCRangeIndex, ABCUInt64Index) |
13 | 15 | from pandas.core.dtypes.missing import isna
|
14 | 16 |
|
15 | 17 | from pandas.core import algorithms
|
@@ -123,6 +125,21 @@ def insert(self, loc, item):
|
123 | 125 | item = self._na_value
|
124 | 126 | return super().insert(loc, item)
|
125 | 127 |
|
| 128 | + def _union(self, other, sort): |
| 129 | + # float | [u]int -> float |
| 130 | + # <T> | <T> -> T |
| 131 | + # <T> | <U> -> object |
| 132 | + needs_cast = ( |
| 133 | + (is_integer_dtype(self.dtype) and is_float_dtype(other.dtype)) or |
| 134 | + (is_integer_dtype(other.dtype) and is_float_dtype(self.dtype)) |
| 135 | + ) |
| 136 | + if needs_cast: |
| 137 | + first = self.astype("float") |
| 138 | + second = other.astype("float") |
| 139 | + return first._union(second, sort) |
| 140 | + else: |
| 141 | + return super()._union(other, sort) |
| 142 | + |
126 | 143 |
|
127 | 144 | _num_index_shared_docs['class_descr'] = """
|
128 | 145 | Immutable ndarray implementing an ordered, sliceable set. The basic object
|
@@ -225,10 +242,24 @@ def _assert_safe_casting(cls, data, subarr):
|
225 | 242 | def _is_compatible_with_other(self, other):
|
226 | 243 | return (
|
227 | 244 | super()._is_compatible_with_other(other)
|
228 |
| - or all(isinstance(type(obj), (ABCInt64Index, ABCRangeIndex)) |
| 245 | + or all(isinstance(type(obj), (ABCInt64Index, |
| 246 | + ABCFloat64Index, |
| 247 | + ABCRangeIndex)) |
229 | 248 | for obj in [self, other])
|
230 | 249 | )
|
231 | 250 |
|
| 251 | + def _union(self, other, sort): |
| 252 | + needs_cast = ( |
| 253 | + (is_integer_dtype(self.dtype) and is_float_dtype(other.dtype)) or |
| 254 | + (is_integer_dtype(other.dtype) and is_float_dtype(self.dtype)) |
| 255 | + ) |
| 256 | + if needs_cast: |
| 257 | + first = self.astype("float") |
| 258 | + second = other.astype("float") |
| 259 | + return first._union(second, sort) |
| 260 | + else: |
| 261 | + return super()._union(other, sort) |
| 262 | + |
232 | 263 |
|
233 | 264 | Int64Index._add_numeric_methods()
|
234 | 265 | Int64Index._add_logical_methods()
|
@@ -301,6 +332,29 @@ def _assert_safe_casting(cls, data, subarr):
|
301 | 332 | raise TypeError('Unsafe NumPy casting, you must '
|
302 | 333 | 'explicitly cast')
|
303 | 334 |
|
| 335 | + def _is_compatible_with_other(self, other): |
| 336 | + # not ABCInt64Index |
| 337 | + # TODO: dedpulicate with Int64Index. |
| 338 | + # TODO: who all needs this? Int, UInt, Float? Range? |
| 339 | + return ( |
| 340 | + super()._is_compatible_with_other(other) |
| 341 | + or all(isinstance(type(obj), (ABCUInt64Index, |
| 342 | + ABCFloat64Index)) |
| 343 | + for obj in [self, other]) |
| 344 | + ) |
| 345 | + |
| 346 | + def _union(self, other, sort): |
| 347 | + needs_cast = ( |
| 348 | + (is_integer_dtype(self.dtype) and is_float_dtype(other.dtype)) or |
| 349 | + (is_integer_dtype(other.dtype) and is_float_dtype(self.dtype)) |
| 350 | + ) |
| 351 | + if needs_cast: |
| 352 | + first = self.astype("float") |
| 353 | + second = other.astype("float") |
| 354 | + return first._union(second, sort) |
| 355 | + else: |
| 356 | + return super()._union(other, sort) |
| 357 | + |
304 | 358 |
|
305 | 359 | UInt64Index._add_numeric_methods()
|
306 | 360 | UInt64Index._add_logical_methods()
|
@@ -447,6 +501,16 @@ def isin(self, values, level=None):
|
447 | 501 | self._validate_index_level(level)
|
448 | 502 | return algorithms.isin(np.array(self), values)
|
449 | 503 |
|
| 504 | + def _is_compatible_with_other(self, other): |
| 505 | + return ( |
| 506 | + super()._is_compatible_with_other(other) |
| 507 | + or all(isinstance(type(obj), (ABCInt64Index, |
| 508 | + ABCFloat64Index, |
| 509 | + ABCUInt64Index, |
| 510 | + ABCRangeIndex)) |
| 511 | + for obj in [self, other]) |
| 512 | + ) |
| 513 | + |
450 | 514 |
|
451 | 515 | Float64Index._add_numeric_methods()
|
452 | 516 | Float64Index._add_logical_methods_disabled()
|
0 commit comments