Skip to content

CLN: avoid try/except in Index methods #37990

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 1 commit into from
Nov 23, 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
10 changes: 4 additions & 6 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2490,12 +2490,10 @@ def _get_unique_index(self, dropna: bool = False):
else:
values = self._values

if dropna:
try:
if self.hasnans:
values = values[~isna(values)]
except NotImplementedError:
pass
if dropna and not isinstance(self, ABCMultiIndex):
# isna not defined for MultiIndex
Comment on lines +2493 to +2494
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is reasonable to consider that ABCMultiIndex is never going to have isna defined?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This came up on a dev call earlier this year and it didn't sound like there was reason for optimism.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isna is tricky because a MI can be multi-valued e.g does isna refer to any value on a level, or all levels be null? it would be reasonable to actually return a multi-value here (e.g. same shape as the MI), but would need to see the implications if this is done.

if self.hasnans:
values = values[~isna(values)]

return self._shallow_copy(values)

Expand Down
63 changes: 29 additions & 34 deletions pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
from pandas.core import algorithms
from pandas.core.arrays import DatetimeArray, PeriodArray, TimedeltaArray
from pandas.core.arrays.datetimelike import DatetimeLikeArrayMixin
from pandas.core.base import IndexOpsMixin
import pandas.core.common as com
import pandas.core.indexes.base as ibase
from pandas.core.indexes.base import Index, _index_shared_docs
Expand Down Expand Up @@ -217,10 +216,6 @@ def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs):
result._data._freq = freq
return result

@doc(IndexOpsMixin.searchsorted, klass="Datetime-like Index")
def searchsorted(self, value, side="left", sorter=None):
return self._data.searchsorted(value, side=side, sorter=sorter)

_can_hold_na = True

_na_value = NaT
Expand Down Expand Up @@ -256,23 +251,23 @@ def min(self, axis=None, skipna=True, *args, **kwargs):
return self._na_value

i8 = self.asi8
try:

if len(i8) and self.is_monotonic_increasing:
# quick check
if len(i8) and self.is_monotonic:
if i8[0] != iNaT:
return self._data._box_func(i8[0])

if self.hasnans:
if skipna:
min_stamp = self[~self._isnan].asi8.min()
else:
return self._na_value
else:
min_stamp = i8.min()
return self._data._box_func(min_stamp)
except ValueError:
if i8[0] != iNaT:
return self._data._box_func(i8[0])

if self.hasnans:
if not skipna:
return self._na_value
i8 = i8[~self._isnan]

if not len(i8):
return self._na_value

min_stamp = i8.min()
return self._data._box_func(min_stamp)

def argmin(self, axis=None, skipna=True, *args, **kwargs):
"""
Returns the indices of the minimum values along an axis.
Expand Down Expand Up @@ -313,23 +308,23 @@ def max(self, axis=None, skipna=True, *args, **kwargs):
return self._na_value

i8 = self.asi8
try:

if len(i8) and self.is_monotonic:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prob can de-duplicate this with min

# quick check
if len(i8) and self.is_monotonic:
if i8[-1] != iNaT:
return self._data._box_func(i8[-1])

if self.hasnans:
if skipna:
max_stamp = self[~self._isnan].asi8.max()
else:
return self._na_value
else:
max_stamp = i8.max()
return self._data._box_func(max_stamp)
except ValueError:
if i8[-1] != iNaT:
return self._data._box_func(i8[-1])

if self.hasnans:
if not skipna:
return self._na_value
i8 = i8[~self._isnan]

if not len(i8):
return self._na_value

max_stamp = i8.max()
return self._data._box_func(max_stamp)

def argmax(self, axis=None, skipna=True, *args, **kwargs):
"""
Returns the indices of the maximum values along an axis.
Expand Down Expand Up @@ -463,7 +458,7 @@ def _partial_date_slice(
vals = self._data._ndarray
unbox = self._data._unbox

if self.is_monotonic:
if self.is_monotonic_increasing:

if len(self) and (
(t1 < self[0] and t2 < self[0]) or (t1 > self[-1] and t2 > self[-1])
Expand Down