|
10 | 10 | DIFFERENT_FREQ_INDEX, IncompatibleFrequency, Period)
|
11 | 11 | from pandas._libs.tslibs.timedeltas import Timedelta, delta_to_nanoseconds
|
12 | 12 | from pandas._libs.tslibs.timestamps import (
|
13 |
| - RoundTo, Timestamp, maybe_integer_op_deprecated, round_nsint64) |
| 13 | + RoundTo, maybe_integer_op_deprecated, round_nsint64) |
14 | 14 | import pandas.compat as compat
|
15 | 15 | from pandas.compat.numpy import function as nv
|
16 | 16 | from pandas.errors import (
|
|
29 | 29 | from pandas.core.dtypes.inference import is_array_like
|
30 | 30 | from pandas.core.dtypes.missing import isna
|
31 | 31 |
|
32 |
| -from pandas.core import missing |
| 32 | +from pandas.core import missing, nanops |
33 | 33 | from pandas.core.algorithms import (
|
34 | 34 | checked_add_with_arr, take, unique1d, value_counts)
|
35 | 35 | import pandas.core.common as com
|
@@ -72,8 +72,6 @@ def cmp_method(self, other):
|
72 | 72 |
|
73 | 73 | class AttributesMixin(object):
|
74 | 74 |
|
75 |
| - _scalar_types = (Period, Timestamp, Timedelta) |
76 |
| - |
77 | 75 | @property
|
78 | 76 | def _attributes(self):
|
79 | 77 | # Inheriting subclass should implement _attributes as a list of strings
|
@@ -1098,7 +1096,7 @@ def _time_shift(self, periods, freq=None):
|
1098 | 1096 | freq = frequencies.to_offset(freq)
|
1099 | 1097 | offset = periods * freq
|
1100 | 1098 | result = self + offset
|
1101 |
| - if getattr(self, 'tz', None): |
| 1099 | + if hasattr(self, 'tz'): |
1102 | 1100 | result._dtype = DatetimeTZDtype(tz=self.tz)
|
1103 | 1101 | return result
|
1104 | 1102 |
|
@@ -1310,38 +1308,32 @@ def _evaluate_compare(self, other, op):
|
1310 | 1308 | result[mask] = filler
|
1311 | 1309 | return result
|
1312 | 1310 |
|
| 1311 | + # -------------------------------------------------------------- |
| 1312 | + # Reductions |
| 1313 | + |
1313 | 1314 | def _reduce(self, name, skipna=True, **kwargs):
|
1314 | 1315 | op = getattr(self, name, None)
|
1315 | 1316 | if op:
|
1316 | 1317 | return op(skipna=skipna)
|
1317 | 1318 | else:
|
1318 |
| - return super()._reduce(name, skipna, **kwargs) |
1319 |
| - |
1320 |
| - # -------------------------------------------------------------- |
1321 |
| - # Reductions |
1322 |
| - |
1323 |
| - def _values_for_reduction(self, skipna=True): |
1324 |
| - if skipna: |
1325 |
| - values = self[~self._isnan] |
1326 |
| - else: |
1327 |
| - values = self |
1328 |
| - return values.asi8 |
| 1319 | + return super(DatetimeLikeArrayMixin, self)._reduce( |
| 1320 | + name, skipna, **kwargs |
| 1321 | + ) |
1329 | 1322 |
|
1330 | 1323 | def min(self, skipna=True):
|
1331 |
| - # TODO: Deduplicate with Datetimelike. |
1332 |
| - # they get to take some shortcuts based on monotonicity. |
1333 |
| - i8 = self._values_for_reduction(skipna=skipna) |
1334 |
| - if len(i8): |
1335 |
| - return self._box_func(i8.min()) |
1336 |
| - else: |
| 1324 | + result = nanops.nanmin(self.asi8, skipna=skipna, mask=self.isna()) |
| 1325 | + if isna(result): |
| 1326 | + # Period._from_ordinal does not handle np.nan gracefully |
1337 | 1327 | return NaT
|
| 1328 | + return self._box_func(result) |
1338 | 1329 |
|
1339 | 1330 | def max(self, skipna=True):
|
1340 |
| - i8 = self._values_for_reduction(skipna=skipna) |
1341 |
| - if len(i8): |
1342 |
| - return self._box_func(i8.max()) |
1343 |
| - else: |
| 1331 | + # TODO: skipna is broken with max. |
| 1332 | + result = nanops.nanmax(self.asi8, skipna=skipna, mask=self.isna()) |
| 1333 | + if isna(result): |
| 1334 | + # Period._from_ordinal does not handle np.nan gracefully |
1344 | 1335 | return NaT
|
| 1336 | + return self._box_func(result) |
1345 | 1337 |
|
1346 | 1338 |
|
1347 | 1339 | DatetimeLikeArrayMixin._add_comparison_ops()
|
|
0 commit comments