def intersection(self, other, sort=False): self._validate_sort_keyword(sort) self._assert_can_do_setop(other) if self.equals(other): return self._get_reconciled_name_object(other) if len(self) == 0: return self.copy() if len(other) == 0: return other.copy() if not isinstance(other, type(self)): result = Index.intersection(self, other, sort=sort) if isinstance(result, type(self)): if result.freq is None: result.freq = to_offset(result.inferred_freq) return result elif ( other.freq is None or self.freq is None or other.freq != self.freq or not other.freq.isAnchored() or (not self.is_monotonic or not other.is_monotonic) ): result = Index.intersection(self, other, sort=sort) # Invalidate the freq of `result`, which may not be correct at # this point, depending on the values. result.freq = None if hasattr(self, "tz"): result = self._shallow_copy( result._values, name=result.name, tz=result.tz, freq=None ) else: result = self._shallow_copy(result._values, name=result.name, freq=None) if result.freq is None: result.freq = to_offset(result.inferred_freq) return result # to make our life easier, "sort" the two ranges if self[0] <= other[0]: left, right = self, other else: left, right = other, self # after sorting, the intersection always starts with the right index # and ends with the index of which the last elements is smallest end = min(left[-1], right[-1]) start = right[0] if end < start: return type(self)(data=[]) else: lslice = slice(*left.slice_locs(start, end)) left_chunk = left.values[lslice] return self._shallow_copy(left_chunk)
def intersection(self, other, sort=False): self._validate_sort_keyword(sort) self._assert_can_do_setop(other) if self.equals(other): return self._get_reconciled_name_object(other) if len(self) == 0: return self.copy() if len(other) == 0: return other.copy() if not isinstance(other, type(self)): result = Index.intersection(self, other, sort=sort) if isinstance(result, type(self)): if result.freq is None: result.freq = to_offset(result.inferred_freq) return result elif (other.freq is None or self.freq is None or other.freq != self.freq or not other.freq.isAnchored() or (not self.is_monotonic or not other.is_monotonic)): result = Index.intersection(self, other, sort=sort) # Invalidate the freq of `result`, which may not be correct at # this point, depending on the values. result.freq = None if hasattr(self, 'tz'): result = self._shallow_copy(result._values, name=result.name, tz=result.tz, freq=None) else: result = self._shallow_copy(result._values, name=result.name, freq=None) if result.freq is None: result.freq = to_offset(result.inferred_freq) return result # to make our life easier, "sort" the two ranges if self[0] <= other[0]: left, right = self, other else: left, right = other, self # after sorting, the intersection always starts with the right index # and ends with the index of which the last elements is smallest end = min(left[-1], right[-1]) start = right[0] if end < start: return type(self)(data=[]) else: lslice = slice(*left.slice_locs(start, end)) left_chunk = left.values[lslice] return self._shallow_copy(left_chunk)
def _get_combined_index( indexes: List[Index], intersect: bool = False, sort: bool = False, copy: bool = False, ) -> Index: """ Return the union or intersection of indexes. Parameters ---------- indexes : list of Index or list objects When intersect=True, do not accept list of lists. intersect : bool, default False If True, calculate the intersection between indexes. Otherwise, calculate the union. sort : bool, default False Whether the result index should come out sorted or not. copy : bool, default False If True, return a copy of the combined index. Returns ------- Index """ # TODO: handle index names! indexes = _get_distinct_objs(indexes) if len(indexes) == 0: index = Index([]) elif len(indexes) == 1: index = indexes[0] elif intersect: index = indexes[0] for other in indexes[1:]: index = index.intersection(other) else: index = union_indexes(indexes, sort=sort) index = ensure_index(index) if sort: try: index = index.sort_values() except TypeError: pass # GH 29879 if copy: index = index.copy() return index
def _intersection(self, other: Index, sort=False) -> Index: """ intersection specialized to the case with matching dtypes. """ if len(self) == 0: return self.copy()._get_reconciled_name_object(other) if len(other) == 0: return other.copy()._get_reconciled_name_object(self) if not isinstance(other, type(self)): result = Index.intersection(self, other, sort=sort) if isinstance(result, type(self)): if result.freq is None: # TODO: no tests rely on this; needed? result = result._with_freq("infer") return result elif not self._can_fast_intersect(other): result = Index._intersection(self, other, sort=sort) # We need to invalidate the freq because Index._intersection # uses _shallow_copy on a view of self._data, which will preserve # self.freq if we're not careful. result = self._wrap_setop_result(other, result) return result._with_freq(None)._with_freq("infer") # to make our life easier, "sort" the two ranges if self[0] <= other[0]: left, right = self, other else: left, right = other, self # after sorting, the intersection always starts with the right index # and ends with the index of which the last elements is smallest end = min(left[-1], right[-1]) start = right[0] if end < start: result = self[:0] else: lslice = slice(*left.slice_locs(start, end)) left_chunk = left._values[lslice] # error: Argument 1 to "_simple_new" of "DatetimeIndexOpsMixin" has # incompatible type "Union[ExtensionArray, Any]"; expected # "Union[DatetimeArray, TimedeltaArray, PeriodArray]" [arg-type] result = type(self)._simple_new(left_chunk) # type: ignore[arg-type] return self._wrap_setop_result(other, result)
def intersection(self, other): """ Specialized intersection for TimedeltaIndex objects. May be much faster than Index.intersection Parameters ---------- other : TimedeltaIndex or array-like Returns ------- y : Index or TimedeltaIndex """ self._assert_can_do_setop(other) if self.equals(other): return self._get_reconciled_name_object(other) if not isinstance(other, TimedeltaIndex): try: other = TimedeltaIndex(other) except (TypeError, ValueError): pass result = Index.intersection(self, other) return result if len(self) == 0: return self if len(other) == 0: return other # to make our life easier, "sort" the two ranges if self[0] <= other[0]: left, right = self, other else: left, right = other, self end = min(left[-1], right[-1]) start = right[0] if end < start: return type(self)(data=[]) else: lslice = slice(*left.slice_locs(start, end)) left_chunk = left.values[lslice] return self._shallow_copy(left_chunk)
def intersection(self, other): """ Specialized intersection for TimedeltaIndex objects. May be much faster than Index.intersection Parameters ---------- other : TimedeltaIndex or array-like Returns ------- y : Index or TimedeltaIndex """ self._assert_can_do_setop(other) if self.equals(other): return self._get_reconciled_name_object(other) if not isinstance(other, TimedeltaIndex): try: other = TimedeltaIndex(other) except (TypeError, ValueError): pass result = Index.intersection(self, other) return result if len(self) == 0: return self if len(other) == 0: return other # to make our life easier, "sort" the two ranges if self[0] <= other[0]: left, right = self, other else: left, right = other, self end = min(left[-1], right[-1]) start = right[0] if end < start: return type(self)(data=[]) else: lslice = slice(*left.slice_locs(start, end)) left_chunk = left.values[lslice] return self._shallow_copy(left_chunk)
def _get_combined_index(indexes, intersect=False, sort=False): # TODO: handle index names! indexes = _get_distinct_objs(indexes) if len(indexes) == 0: index = Index([]) elif len(indexes) == 1: index = indexes[0] elif intersect: index = indexes[0] for other in indexes[1:]: index = index.intersection(other) else: index = _union_indexes(indexes, sort=sort) index = ensure_index(index) if sort: try: index = index.sort_values() except TypeError: pass return index
def _get_combined_index(indexes, intersect=False, sort=False): # TODO: handle index names! indexes = com.get_distinct_objs(indexes) if len(indexes) == 0: index = Index([]) elif len(indexes) == 1: index = indexes[0] elif intersect: index = indexes[0] for other in indexes[1:]: index = index.intersection(other) else: index = _union_indexes(indexes, sort=sort) index = ensure_index(index) if sort: try: index = index.sort_values() except TypeError: pass return index
def _get_combined_index(indexes, intersect=False, sort=False): """ Return the union or intersection of indexes. Parameters ---------- indexes : list of Index or list objects When intersect=True, do not accept list of lists. intersect : bool, default False If True, calculate the intersection between indexes. Otherwise, calculate the union. sort : bool, default False Whether the result index should come out sorted or not. Returns ------- Index """ # TODO: handle index names! indexes = _get_distinct_objs(indexes) if len(indexes) == 0: index = Index([]) elif len(indexes) == 1: index = indexes[0] elif intersect: index = indexes[0] for other in indexes[1:]: index = index.intersection(other) else: index = _union_indexes(indexes, sort=sort) index = ensure_index(index) if sort: try: index = index.sort_values() except TypeError: pass return index
def intersection(self, other, sort=False): """ Specialized intersection for DatetimeIndex/TimedeltaIndex. May be much faster than Index.intersection Parameters ---------- other : Same type as self or array-like sort : False or None, default False Sort the resulting index if possible. .. versionadded:: 0.24.0 .. versionchanged:: 0.24.1 Changed the default to ``False`` to match the behaviour from before 0.24.0. .. versionchanged:: 0.25.0 The `sort` keyword is added Returns ------- y : Index or same type as self """ self._validate_sort_keyword(sort) self._assert_can_do_setop(other) if self.equals(other): return self._get_reconciled_name_object(other) if len(self) == 0: return self.copy() if len(other) == 0: return other.copy() if not isinstance(other, type(self)): result = Index.intersection(self, other, sort=sort) if isinstance(result, type(self)): if result.freq is None: result._set_freq("infer") return result elif ( other.freq is None or self.freq is None or other.freq != self.freq or not other.freq.is_anchored() or (not self.is_monotonic or not other.is_monotonic) ): result = Index.intersection(self, other, sort=sort) # Invalidate the freq of `result`, which may not be correct at # this point, depending on the values. result._set_freq(None) result = self._shallow_copy(result._data, name=result.name) if result.freq is None: result._set_freq("infer") return result # to make our life easier, "sort" the two ranges if self[0] <= other[0]: left, right = self, other else: left, right = other, self # after sorting, the intersection always starts with the right index # and ends with the index of which the last elements is smallest end = min(left[-1], right[-1]) start = right[0] if end < start: return type(self)(data=[]) else: lslice = slice(*left.slice_locs(start, end)) left_chunk = left.values[lslice] return self._shallow_copy(left_chunk)
def intersection(self, other, sort=False): """ Specialized intersection for DatetimeIndex/TimedeltaIndex. May be much faster than Index.intersection Parameters ---------- other : Same type as self or array-like sort : False or None, default False Sort the resulting index if possible. .. versionadded:: 0.24.0 .. versionchanged:: 0.24.1 Changed the default to ``False`` to match the behaviour from before 0.24.0. .. versionchanged:: 0.25.0 The `sort` keyword is added Returns ------- y : Index or same type as self """ self._validate_sort_keyword(sort) self._assert_can_do_setop(other) if self.equals(other): return self._get_reconciled_name_object(other) if len(self) == 0: return self.copy()._get_reconciled_name_object(other) if len(other) == 0: return other.copy()._get_reconciled_name_object(self) if not isinstance(other, type(self)): result = Index.intersection(self, other, sort=sort) if isinstance(result, type(self)): if result.freq is None: # TODO: no tests rely on this; needed? result = result._with_freq("infer") return result elif not self._can_fast_intersect(other): result = Index.intersection(self, other, sort=sort) # We need to invalidate the freq because Index.intersection # uses _shallow_copy on a view of self._data, which will preserve # self.freq if we're not careful. return result._with_freq(None)._with_freq("infer") # to make our life easier, "sort" the two ranges if self[0] <= other[0]: left, right = self, other else: left, right = other, self # after sorting, the intersection always starts with the right index # and ends with the index of which the last elements is smallest end = min(left[-1], right[-1]) start = right[0] if end < start: result = type(self)(data=[], dtype=self.dtype, freq=self.freq) else: lslice = slice(*left.slice_locs(start, end)) left_chunk = left._values[lslice] result = type(self)._simple_new(left_chunk) return self._wrap_setop_result(other, result)