|
9 | 9 | FrozenSet,
|
10 | 10 | Hashable,
|
11 | 11 | List,
|
12 |
| - NewType, |
13 | 12 | Optional,
|
14 | 13 | Sequence,
|
15 | 14 | Tuple,
|
|
24 | 23 | from pandas._libs import algos as libalgos, index as libindex, lib
|
25 | 24 | import pandas._libs.join as libjoin
|
26 | 25 | from pandas._libs.lib import is_datetime_array, no_default
|
27 |
| -from pandas._libs.tslibs import IncompatibleFrequency, OutOfBoundsDatetime, Timestamp |
| 26 | +from pandas._libs.tslibs import OutOfBoundsDatetime, Timestamp |
| 27 | +from pandas._libs.tslibs.period import IncompatibleFrequency |
28 | 28 | from pandas._libs.tslibs.timezones import tz_compare
|
29 | 29 | from pandas._typing import AnyArrayLike, Dtype, DtypeObj, Label
|
| 30 | +from pandas.compat import set_function_name |
30 | 31 | from pandas.compat.numpy import function as nv
|
31 | 32 | from pandas.errors import DuplicateLabelError, InvalidIndexError
|
32 | 33 | from pandas.util._decorators import Appender, cache_readonly, doc
|
33 | 34 |
|
| 35 | +from pandas.core.dtypes import concat as _concat |
34 | 36 | from pandas.core.dtypes.cast import (
|
35 | 37 | maybe_cast_to_integer_array,
|
36 | 38 | validate_numeric_casting,
|
|
66 | 68 | from pandas.core.dtypes.concat import concat_compat
|
67 | 69 | from pandas.core.dtypes.generic import (
|
68 | 70 | ABCCategorical,
|
| 71 | + ABCDataFrame, |
69 | 72 | ABCDatetimeIndex,
|
70 | 73 | ABCMultiIndex,
|
71 | 74 | ABCPandasArray,
|
|
76 | 79 | )
|
77 | 80 | from pandas.core.dtypes.missing import array_equivalent, isna
|
78 | 81 |
|
79 |
| -from pandas.core import missing, ops |
| 82 | +from pandas.core import ops |
80 | 83 | from pandas.core.accessor import CachedAccessor
|
81 | 84 | import pandas.core.algorithms as algos
|
82 | 85 | from pandas.core.arrays import Categorical, ExtensionArray
|
|
85 | 88 | import pandas.core.common as com
|
86 | 89 | from pandas.core.indexers import deprecate_ndim_indexing
|
87 | 90 | from pandas.core.indexes.frozen import FrozenList
|
| 91 | +import pandas.core.missing as missing |
88 | 92 | from pandas.core.ops import get_op_result_name
|
89 | 93 | from pandas.core.ops.invalid import make_invalid_op
|
90 | 94 | from pandas.core.sorting import ensure_key_mapped, nargsort
|
|
118 | 122 | str_t = str
|
119 | 123 |
|
120 | 124 |
|
121 |
| -_o_dtype = np.dtype(object) |
| 125 | +def _make_arithmetic_op(op, cls): |
| 126 | + def index_arithmetic_method(self, other): |
| 127 | + if isinstance(other, (ABCSeries, ABCDataFrame, ABCTimedeltaIndex)): |
| 128 | + return NotImplemented |
| 129 | + |
| 130 | + from pandas import Series |
| 131 | + |
| 132 | + result = op(Series(self), other) |
| 133 | + if isinstance(result, tuple): |
| 134 | + return (Index(result[0]), Index(result[1])) |
| 135 | + return Index(result) |
122 | 136 |
|
| 137 | + name = f"__{op.__name__}__" |
| 138 | + return set_function_name(index_arithmetic_method, name, cls) |
123 | 139 |
|
124 |
| -_Identity = NewType("_Identity", object) |
| 140 | + |
| 141 | +_o_dtype = np.dtype(object) |
| 142 | +_Identity = object |
125 | 143 |
|
126 | 144 |
|
127 | 145 | def _new_Index(cls, d):
|
@@ -220,7 +238,7 @@ def _outer_indexer(self, left, right):
|
220 | 238 |
|
221 | 239 | _typ = "index"
|
222 | 240 | _data: Union[ExtensionArray, np.ndarray]
|
223 |
| - _id: _Identity |
| 241 | + _id = None |
224 | 242 | _name: Label = None
|
225 | 243 | # MultiIndex.levels previously allowed setting the index name. We
|
226 | 244 | # don't allow this anymore, and raise if it happens rather than
|
@@ -435,9 +453,8 @@ def _simple_new(cls, values, name: Label = None):
|
435 | 453 | result._index_data = values
|
436 | 454 | result._name = name
|
437 | 455 | result._cache = {}
|
438 |
| - result._reset_identity() |
439 | 456 |
|
440 |
| - return result |
| 457 | + return result._reset_identity() |
441 | 458 |
|
442 | 459 | @cache_readonly
|
443 | 460 | def _constructor(self):
|
@@ -541,16 +558,15 @@ def is_(self, other) -> bool:
|
541 | 558 | --------
|
542 | 559 | Index.identical : Works like ``Index.is_`` but also checks metadata.
|
543 | 560 | """
|
544 |
| - try: |
545 |
| - return self._id is other._id |
546 |
| - except AttributeError: |
547 |
| - return False |
| 561 | + # use something other than None to be clearer |
| 562 | + return self._id is getattr(other, "_id", Ellipsis) and self._id is not None |
548 | 563 |
|
549 |
| - def _reset_identity(self) -> None: |
| 564 | + def _reset_identity(self): |
550 | 565 | """
|
551 | 566 | Initializes or resets ``_id`` attribute with new object.
|
552 | 567 | """
|
553 |
| - self._id = _Identity(object()) |
| 568 | + self._id = _Identity() |
| 569 | + return self |
554 | 570 |
|
555 | 571 | def _cleanup(self):
|
556 | 572 | self._engine.clear_mapping()
|
@@ -4207,7 +4223,7 @@ def _concat(self, to_concat, name):
|
4207 | 4223 | """
|
4208 | 4224 | to_concat = [x._values if isinstance(x, Index) else x for x in to_concat]
|
4209 | 4225 |
|
4210 |
| - result = concat_compat(to_concat) |
| 4226 | + result = _concat.concat_compat(to_concat) |
4211 | 4227 | return Index(result, name=name)
|
4212 | 4228 |
|
4213 | 4229 | def putmask(self, mask, value):
|
@@ -5363,12 +5379,22 @@ def _cmp_method(self, other, op):
|
5363 | 5379 | """
|
5364 | 5380 | Wrapper used to dispatch comparison operations.
|
5365 | 5381 | """
|
5366 |
| - if self.is_(other): |
| 5382 | + from .multi import MultiIndex |
| 5383 | + |
| 5384 | + if self.is_(other) and not isinstance(self, MultiIndex): |
5367 | 5385 | # short-circuit when other is same as self
|
5368 |
| - if op in (operator.eq, operator.le, operator.ge): |
5369 |
| - return np.ones(self.shape, dtype=bool) |
5370 |
| - elif op in (operator.ne, operator.lt, operator.gt): |
5371 |
| - return np.zeros(self.shape, dtype=bool) |
| 5386 | + bool_arr_type, na_bool = { |
| 5387 | + operator.eq: (np.ones, False), |
| 5388 | + operator.le: (np.ones, False), |
| 5389 | + operator.ge: (np.ones, False), |
| 5390 | + operator.ne: (np.zeros, True), |
| 5391 | + operator.lt: (np.zeros, True), |
| 5392 | + operator.gt: (np.zeros, True), |
| 5393 | + }[op] |
| 5394 | + bool_arr = bool_arr_type(self.shape, dtype=bool) |
| 5395 | + if self._can_hold_na: |
| 5396 | + bool_arr[isna(self)] = na_bool |
| 5397 | + return bool_arr |
5372 | 5398 |
|
5373 | 5399 | if isinstance(other, (np.ndarray, Index, ABCSeries, ExtensionArray)):
|
5374 | 5400 | if len(self) != len(other):
|
|
0 commit comments