Skip to content

Commit 8d5cd1c

Browse files
jbrockmendeljreback
authored andcommitted
ENH: Implement PeriodIndex.intersection without object-dtype cast (#30666)
1 parent 90d7ad2 commit 8d5cd1c

File tree

3 files changed

+36
-22
lines changed

3 files changed

+36
-22
lines changed

pandas/core/indexes/base.py

+5-16
Original file line numberDiff line numberDiff line change
@@ -2408,14 +2408,8 @@ def intersection(self, other, sort=False):
24082408
return this.intersection(other, sort=sort)
24092409

24102410
# TODO(EA): setops-refactor, clean all this up
2411-
if is_period_dtype(self):
2412-
lvals = self._ndarray_values
2413-
else:
2414-
lvals = self._values
2415-
if is_period_dtype(other):
2416-
rvals = other._ndarray_values
2417-
else:
2418-
rvals = other._values
2411+
lvals = self._values
2412+
rvals = other._values
24192413

24202414
if self.is_monotonic and other.is_monotonic:
24212415
try:
@@ -2434,18 +2428,13 @@ def intersection(self, other, sort=False):
24342428
indexer = indexer[indexer != -1]
24352429

24362430
taken = other.take(indexer)
2431+
res_name = get_op_result_name(self, other)
24372432

24382433
if sort is None:
24392434
taken = algos.safe_sort(taken.values)
2440-
if self.name != other.name:
2441-
name = None
2442-
else:
2443-
name = self.name
2444-
return self._shallow_copy(taken, name=name)
2445-
2446-
if self.name != other.name:
2447-
taken.name = None
2435+
return self._shallow_copy(taken, name=res_name)
24482436

2437+
taken.name = res_name
24492438
return taken
24502439

24512440
def difference(self, other, sort=None):

pandas/core/indexes/datetimelike.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -721,12 +721,9 @@ def intersection(self, other, sort=False):
721721
# this point, depending on the values.
722722

723723
result._set_freq(None)
724-
if hasattr(self, "tz"):
725-
result = self._shallow_copy(
726-
result._values, name=result.name, tz=result.tz, freq=None
727-
)
728-
else:
729-
result = self._shallow_copy(result._values, name=result.name, freq=None)
724+
result = self._shallow_copy(
725+
result._data, name=result.name, dtype=result.dtype, freq=None
726+
)
730727
if result.freq is None:
731728
result._set_freq("infer")
732729
return result

pandas/core/indexes/period.py

+28
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
ensure_platform_int,
1313
is_bool_dtype,
1414
is_datetime64_any_dtype,
15+
is_dtype_equal,
1516
is_float,
1617
is_float_dtype,
1718
is_integer,
@@ -782,6 +783,9 @@ def join(self, other, how="left", level=None, return_indexers=False, sort=False)
782783
return self._apply_meta(result), lidx, ridx
783784
return self._apply_meta(result)
784785

786+
# ------------------------------------------------------------------------
787+
# Set Operation Methods
788+
785789
def _assert_can_do_setop(self, other):
786790
super()._assert_can_do_setop(other)
787791

@@ -799,6 +803,30 @@ def _wrap_setop_result(self, other, result):
799803
result.name = name
800804
return result
801805

806+
def intersection(self, other, sort=False):
807+
self._validate_sort_keyword(sort)
808+
self._assert_can_do_setop(other)
809+
res_name = get_op_result_name(self, other)
810+
other = ensure_index(other)
811+
812+
if self.equals(other):
813+
return self._get_reconciled_name_object(other)
814+
815+
if not is_dtype_equal(self.dtype, other.dtype):
816+
# TODO: fastpath for if we have a different PeriodDtype
817+
this = self.astype("O")
818+
other = other.astype("O")
819+
return this.intersection(other, sort=sort)
820+
821+
i8self = Int64Index._simple_new(self.asi8)
822+
i8other = Int64Index._simple_new(other.asi8)
823+
i8result = i8self.intersection(i8other, sort=sort)
824+
825+
result = self._shallow_copy(np.asarray(i8result, dtype=np.int64), name=res_name)
826+
return result
827+
828+
# ------------------------------------------------------------------------
829+
802830
def _apply_meta(self, rawarr):
803831
if not isinstance(rawarr, PeriodIndex):
804832
rawarr = PeriodIndex._simple_new(rawarr, freq=self.freq, name=self.name)

0 commit comments

Comments
 (0)