Skip to content

REF: Fix PeriodIndex._outer_indexer -> share remaining set methods #39331

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@

if TYPE_CHECKING:
from pandas import MultiIndex, RangeIndex, Series
from pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin


__all__ = ["Index"]
Expand Down Expand Up @@ -2895,9 +2896,8 @@ def _union(self, other, sort):

@final
def _wrap_setop_result(self, other, result):
if isinstance(self, (ABCDatetimeIndex, ABCTimedeltaIndex)) and isinstance(
result, np.ndarray
):
if needs_i8_conversion(self.dtype) and isinstance(result, np.ndarray):
self = cast("DatetimeIndexOpsMixin", self)
result = type(self._data)._simple_new(result, dtype=self.dtype)
elif is_categorical_dtype(self.dtype) and isinstance(result, np.ndarray):
result = Categorical(result, dtype=self.dtype)
Expand Down
14 changes: 7 additions & 7 deletions pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,13 @@ def insert(self, loc: int, item):
# --------------------------------------------------------------------
# Join/Set Methods

_inner_indexer = _join_i8_wrapper(libjoin.inner_join_indexer)
_outer_indexer = _join_i8_wrapper(libjoin.outer_join_indexer)
_left_indexer = _join_i8_wrapper(libjoin.left_join_indexer)
_left_indexer_unique = _join_i8_wrapper(
libjoin.left_join_indexer_unique, with_indexers=False
)

def _get_join_freq(self, other):
"""
Get the freq to attach to the result of a join operation.
Expand Down Expand Up @@ -832,13 +839,6 @@ def _union(self, other, sort):
# Join Methods
_join_precedence = 10

_inner_indexer = _join_i8_wrapper(libjoin.inner_join_indexer)
_outer_indexer = _join_i8_wrapper(libjoin.outer_join_indexer)
_left_indexer = _join_i8_wrapper(libjoin.left_join_indexer)
_left_indexer_unique = _join_i8_wrapper(
libjoin.left_join_indexer_unique, with_indexers=False
)

def join(
self, other, how: str = "left", level=None, return_indexers=False, sort=False
):
Expand Down
29 changes: 1 addition & 28 deletions pandas/core/indexes/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,11 @@
)
import pandas.core.common as com
import pandas.core.indexes.base as ibase
from pandas.core.indexes.base import ensure_index, maybe_extract_name
from pandas.core.indexes.base import maybe_extract_name
from pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin
from pandas.core.indexes.datetimes import DatetimeIndex, Index
from pandas.core.indexes.extension import inherit_names
from pandas.core.indexes.numeric import Int64Index
from pandas.core.ops import get_op_result_name

_index_doc_kwargs = dict(ibase._index_doc_kwargs)
_index_doc_kwargs.update({"target_klass": "PeriodIndex or list of Periods"})
Expand Down Expand Up @@ -580,32 +579,6 @@ def _get_string_slice(self, key: str):
except KeyError as err:
raise KeyError(key) from err

# ------------------------------------------------------------------------
# Set Operation Methods

def _setop(self, other, sort, opname: str):
"""
Perform a set operation by dispatching to the Int64Index implementation.
"""
self._validate_sort_keyword(sort)
self._assert_can_do_setop(other)
res_name = get_op_result_name(self, other)
other = ensure_index(other)

i8self = Int64Index._simple_new(self.asi8)
i8other = Int64Index._simple_new(other.asi8)
i8result = getattr(i8self, opname)(i8other, sort=sort)

parr = type(self._data)(np.asarray(i8result, dtype=np.int64), dtype=self.dtype)
result = type(self)._simple_new(parr, name=res_name)
return result

def _intersection(self, other, sort=False):
return self._setop(other, sort, opname="intersection")

def _union(self, other, sort):
return self._setop(other, sort, opname="_union")

# ------------------------------------------------------------------------

def memory_usage(self, deep: bool = False) -> int:
Expand Down
8 changes: 0 additions & 8 deletions pandas/core/indexes/range.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,14 +685,6 @@ def symmetric_difference(self, other, result_name=None, sort=None):

# --------------------------------------------------------------------

@doc(Int64Index.join)
def join(self, other, how="left", level=None, return_indexers=False, sort=False):
if how == "outer" and self is not other:
# note: could return RangeIndex in more circumstances
return self._int64index.join(other, how, level, return_indexers, sort)

return super().join(other, how, level, return_indexers, sort)

def _concat(self, indexes, name):
"""
Overriding parent method for the case of all RangeIndex instances.
Expand Down
8 changes: 8 additions & 0 deletions pandas/tests/indexes/period/test_join.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@


class TestJoin:
def test_join_outer_indexer(self):
pi = period_range("1/1/2000", "1/20/2000", freq="D")

result = pi._outer_indexer(pi._values, pi._values)
tm.assert_numpy_array_equal(result[0], pi.asi8)
tm.assert_numpy_array_equal(result[1], np.arange(len(pi), dtype=np.int64))
tm.assert_numpy_array_equal(result[2], np.arange(len(pi), dtype=np.int64))

def test_joins(self, join_type):
index = period_range("1/1/2000", "1/20/2000", freq="D")

Expand Down