Skip to content

Commit a2c3cc5

Browse files
committed
Gid rid of MultiIndex conversion in IntervalIndex.intersection
1 parent 64104ec commit a2c3cc5

File tree

1 file changed

+58
-1
lines changed

1 file changed

+58
-1
lines changed

pandas/core/indexes/interval.py

+58-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
is_interval_dtype, is_list_like, is_number, is_object_dtype, is_scalar)
2020
from pandas.core.dtypes.missing import isna
2121

22+
import pandas.core.algorithms as algos
2223
from pandas.core.arrays.interval import IntervalArray, _interval_shared_docs
2324
import pandas.core.common as com
2425
import pandas.core.indexes.base as ibase
@@ -1090,6 +1091,63 @@ def equals(self, other):
10901091
def overlaps(self, other):
10911092
return self._data.overlaps(other)
10921093

1094+
def intersection2(self, other, sort=False):
1095+
other = self._as_like_interval_index(other)
1096+
1097+
# GH 19016: ensure set op will not return a prohibited dtype
1098+
subtypes = [self.dtype.subtype, other.dtype.subtype]
1099+
common_subtype = find_common_type(subtypes)
1100+
if is_object_dtype(common_subtype):
1101+
msg = ('can only do intersection between two IntervalIndex '
1102+
'objects that have compatible dtypes')
1103+
raise TypeError(msg)
1104+
1105+
try:
1106+
lindexer = other.left.get_indexer(self.left)
1107+
rindexer = other.right.get_indexer(self.right)
1108+
except Exception:
1109+
# duplicates
1110+
lindexer = algos.unique1d(
1111+
other.left.get_indexer_non_unique(self.left)[0])
1112+
rindexer = algos.unique1d(
1113+
other.right.get_indexer_non_unique(self.right)[0])
1114+
1115+
match = (lindexer == rindexer) & (lindexer != -1)
1116+
indexer = lindexer.take(match.nonzero()[0])
1117+
taken = other.take(indexer)
1118+
1119+
return taken
1120+
1121+
def intersection(self, other, sort=False):
1122+
other = self._as_like_interval_index(other)
1123+
1124+
# GH 19016: ensure set op will not return a prohibited dtype
1125+
subtypes = [self.dtype.subtype, other.dtype.subtype]
1126+
common_subtype = find_common_type(subtypes)
1127+
if is_object_dtype(common_subtype):
1128+
msg = ('can only do intersection between two IntervalIndex '
1129+
'objects that have compatible dtypes')
1130+
raise TypeError(msg)
1131+
1132+
try:
1133+
lindexer = self.left.get_indexer(other.left)
1134+
rindexer = self.right.get_indexer(other.right)
1135+
except Exception:
1136+
# duplicates
1137+
lindexer = algos.unique1d(
1138+
self.left.get_indexer_non_unique(other.left)[0])
1139+
rindexer = algos.unique1d(
1140+
self.right.get_indexer_non_unique(other.right)[0])
1141+
1142+
match = (lindexer == rindexer) & (lindexer != -1)
1143+
indexer = lindexer.take(match.nonzero()[0])
1144+
taken = self.take(indexer)
1145+
1146+
if sort is None:
1147+
taken = taken.sort_values()
1148+
1149+
return taken
1150+
10931151
def _setop(op_name, sort=None):
10941152
def func(self, other, sort=sort):
10951153
other = self._as_like_interval_index(other)
@@ -1125,7 +1183,6 @@ def is_all_dates(self):
11251183
return False
11261184

11271185
union = _setop('union')
1128-
intersection = _setop('intersection', sort=False)
11291186
difference = _setop('difference')
11301187
symmetric_difference = _setop('symmetric_difference')
11311188

0 commit comments

Comments
 (0)