Skip to content

CLN: make MultiIndex._shallow_copy signature match other subclasses #37985

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 2 commits into from
Nov 21, 2020
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
8 changes: 6 additions & 2 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3986,7 +3986,11 @@ def _join_monotonic(self, other, how="left", return_indexers=False):
else:
return join_index

def _wrap_joined_index(self, joined, other):
def _wrap_joined_index(
self: _IndexT, joined: np.ndarray, other: _IndexT
) -> _IndexT:
assert other.dtype == self.dtype

if isinstance(self, ABCMultiIndex):
name = self.names if self.names == other.names else None
else:
Expand Down Expand Up @@ -4188,7 +4192,7 @@ def _is_memory_usage_qualified(self) -> bool:
"""
return self.is_object()

def is_type_compatible(self, kind) -> bool:
def is_type_compatible(self, kind: str_t) -> bool:
"""
Whether the index type is compatible with the provided type.
"""
Expand Down
60 changes: 30 additions & 30 deletions pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,36 @@ def _format_attrs(self):
attrs.append(("freq", freq))
return attrs

def _summary(self, name=None) -> str:
"""
Return a summarized representation.

Parameters
----------
name : str
Name to use in the summary representation.

Returns
-------
str
Summarized representation of the index.
"""
formatter = self._formatter_func
if len(self) > 0:
index_summary = f", {formatter(self[0])} to {formatter(self[-1])}"
else:
index_summary = ""

if name is None:
name = type(self).__name__
result = f"{name}: {len(self)} entries{index_summary}"
if self.freq:
result += f"\nFreq: {self.freqstr}"

# display as values, not quoted
result = result.replace("'", "")
return result

# --------------------------------------------------------------------
# Indexing Methods

Expand Down Expand Up @@ -507,36 +537,6 @@ def where(self, cond, other=None):
arr = self._data._from_backing_data(result)
return type(self)._simple_new(arr, name=self.name)

def _summary(self, name=None) -> str:
"""
Return a summarized representation.

Parameters
----------
name : str
Name to use in the summary representation.

Returns
-------
str
Summarized representation of the index.
"""
formatter = self._formatter_func
if len(self) > 0:
index_summary = f", {formatter(self[0])} to {formatter(self[-1])}"
else:
index_summary = ""

if name is None:
name = type(self).__name__
result = f"{name}: {len(self)} entries{index_summary}"
if self.freq:
result += f"\nFreq: {self.freqstr}"

# display as values, not quoted
result = result.replace("'", "")
return result

def shift(self, periods=1, freq=None):
"""
Shift index by desired number of time frequency increments.
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/indexes/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,8 +814,8 @@ def slice_indexer(self, start=None, end=None, step=None, kind=None):

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

def is_type_compatible(self, typ) -> bool:
return typ == self.inferred_type or typ == "datetime"
def is_type_compatible(self, kind: str) -> bool:
return kind == self.inferred_type or kind == "datetime"

@property
def inferred_type(self) -> str:
Expand Down
65 changes: 28 additions & 37 deletions pandas/core/indexes/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -1065,53 +1065,26 @@ def _engine(self):

@property
def _constructor(self):
return MultiIndex.from_tuples
return type(self).from_tuples

@doc(Index._shallow_copy)
def _shallow_copy(
self,
values=None,
name=lib.no_default,
levels=None,
codes=None,
sortorder=None,
names=lib.no_default,
):
if names is not lib.no_default and name is not lib.no_default:
raise TypeError("Can only provide one of `names` and `name`")
elif names is lib.no_default:
names = name if name is not lib.no_default else self.names
def _shallow_copy(self, values=None, name=lib.no_default):
names = name if name is not lib.no_default else self.names

if values is not None:
assert levels is None and codes is None
return MultiIndex.from_tuples(values, sortorder=sortorder, names=names)
return type(self).from_tuples(values, sortorder=None, names=names)

levels = levels if levels is not None else self.levels
codes = codes if codes is not None else self.codes

result = MultiIndex(
levels=levels,
codes=codes,
sortorder=sortorder,
result = type(self)(
levels=self.levels,
codes=self.codes,
sortorder=None,
names=names,
verify_integrity=False,
)
result._cache = self._cache.copy()
result._cache.pop("levels", None) # GH32669
return result

def symmetric_difference(self, other, result_name=None, sort=None):
# On equal symmetric_difference MultiIndexes the difference is empty.
# Therefore, an empty MultiIndex is returned GH13490
tups = Index.symmetric_difference(self, other, result_name, sort)
if len(tups) == 0:
return MultiIndex(
levels=[[] for _ in range(self.nlevels)],
codes=[[] for _ in range(self.nlevels)],
names=tups.name,
)
return type(self).from_tuples(tups, names=tups.name)

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

def copy(
Expand Down Expand Up @@ -1177,12 +1150,18 @@ def copy(
if codes is None:
codes = deepcopy(self.codes)

new_index = self._shallow_copy(
levels = levels if levels is not None else self.levels
codes = codes if codes is not None else self.codes

new_index = type(self)(
levels=levels,
codes=codes,
names=names,
sortorder=self.sortorder,
names=names,
verify_integrity=False,
)
new_index._cache = self._cache.copy()
new_index._cache.pop("levels", None) # GH32669

if dtype:
warnings.warn(
Expand Down Expand Up @@ -3612,6 +3591,18 @@ def _convert_can_do_setop(self, other):

return other, result_names

def symmetric_difference(self, other, result_name=None, sort=None):
# On equal symmetric_difference MultiIndexes the difference is empty.
# Therefore, an empty MultiIndex is returned GH13490
tups = Index.symmetric_difference(self, other, result_name, sort)
if len(tups) == 0:
return type(self)(
levels=[[] for _ in range(self.nlevels)],
codes=[[] for _ in range(self.nlevels)],
names=tups.name,
)
return type(self).from_tuples(tups, names=tups.name)

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

@doc(Index.astype)
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/indexes/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def __new__(

@property
def values(self) -> np.ndarray:
return np.asarray(self)
return np.asarray(self, dtype=object)

def _maybe_convert_timedelta(self, other):
"""
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/indexes/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,8 @@ def _maybe_cast_slice_bound(self, label, side: str, kind):

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

def is_type_compatible(self, typ) -> bool:
return typ == self.inferred_type or typ == "timedelta"
def is_type_compatible(self, kind: str) -> bool:
return kind == self.inferred_type or kind == "timedelta"

@property
def inferred_type(self) -> str:
Expand Down