Skip to content

Commit c68b9b5

Browse files
committed
review comments
1 parent ae8f9eb commit c68b9b5

File tree

7 files changed

+21
-14
lines changed

7 files changed

+21
-14
lines changed

doc/source/whatsnew/v0.24.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ ExtensionType Changes
512512
- :meth:`Series.astype` and :meth:`DataFrame.astype` now dispatch to :meth:`ExtensionArray.astype` (:issue:`21185:`).
513513
- Slicing a single row of a ``DataFrame`` with multiple ExtensionArrays of the same type now preserves the dtype, rather than coercing to object (:issue:`22784`)
514514
- Added :meth:`pandas.api.types.register_extension_dtype` to register an extension type with pandas (:issue:`22664`)
515+
- Support for reduction operations such as ``sum``, ``mean`` via opt-in base class method override (:issue:`22762`)
515516

516517
.. _whatsnew_0240.api.incompatibilities:
517518

pandas/conftest.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ def all_arithmetic_operators(request):
132132

133133

134134
_all_numeric_reductions = ['sum', 'max', 'min',
135-
'mean', 'prod', 'std', 'var', 'median']
135+
'mean', 'prod', 'std', 'var', 'median',
136+
'kurt', 'skew']
136137

137138

138139
@pytest.fixture(params=_all_numeric_reductions)

pandas/core/arrays/base.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -675,17 +675,20 @@ def _ndarray_values(self):
675675
return np.array(self)
676676

677677
def _reduce(self, name, skipna=True, **kwargs):
678-
"""Return a scalar result of performing the op
678+
"""Return a scalar result of performing the reduction operation.
679679
680680
Parameters
681681
----------
682682
name : str
683-
name of the function
683+
name of the function, support values are:
684+
{any, all, min, max, sum, mean, median, prod,
685+
std, var, sem, kurt, skew}
684686
axis : int, default 0
685687
axis over which to apply, defined as 0 currently
686688
skipna : bool, default True
687689
if True, skip NaN values
688690
kwargs : dict
691+
ddof is the only supported kwarg
689692
690693
Returns
691694
-------
@@ -695,7 +698,8 @@ def _reduce(self, name, skipna=True, **kwargs):
695698
------
696699
TypeError : subclass does not define reductions
697700
"""
698-
raise TypeError
701+
raise TypeError("cannot perform {name} with type {dtype}".format(
702+
name=name, dtype=self.dtype))
699703

700704

701705
class ExtensionOpsMixin(object):

pandas/core/arrays/integer.py

+5-7
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ def cmp_method(self, other):
530530
name = '__{name}__'.format(name=op.__name__)
531531
return set_function_name(cmp_method, name, cls)
532532

533-
def _reduce(self, name, axis=0, skipna=True, **kwargs):
533+
def _reduce(self, name, skipna=True, **kwargs):
534534
data = self._data
535535
mask = self._mask
536536

@@ -540,17 +540,15 @@ def _reduce(self, name, axis=0, skipna=True, **kwargs):
540540
data[mask] = self._na_value
541541

542542
op = getattr(nanops, 'nan' + name)
543-
result = op(data, axis=axis, skipna=skipna, mask=mask)
543+
result = op(data, axis=0, skipna=skipna, mask=mask)
544544

545-
# if we have a boolean op, provide coercion back to a bool
546-
# type if possible
545+
# if we have a boolean op, don't coerce
547546
if name in ['any', 'all']:
548-
if is_integer(result) or is_float(result):
549-
result = bool(int(result))
547+
pass
550548

551549
# if we have a numeric op, provide coercion back to an integer
552550
# type if possible
553-
elif not isna(result):
551+
elif notna(result):
554552
int_result = int(result)
555553
if int_result == result:
556554
result = int_result

pandas/core/series.py

+3
Original file line numberDiff line numberDiff line change
@@ -3404,6 +3404,9 @@ def _reduce(self, op, name, axis=0, skipna=True, numeric_only=None,
34043404
with np.errstate(all='ignore'):
34053405
return op(delegate, skipna=skipna, **kwds)
34063406

3407+
# TODO(EA) dispatch to Index
3408+
# remove once all internals extension types are
3409+
# moved to ExtensionArrays
34073410
return delegate._reduce(op=op, name=name, axis=axis, skipna=skipna,
34083411
numeric_only=numeric_only,
34093412
filter_type=filter_type, **kwds)

pandas/tests/extension/decimal/array.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def _na_value(self):
137137
def _concat_same_type(cls, to_concat):
138138
return cls(np.concatenate([x._data for x in to_concat]))
139139

140-
def _reduce(self, name, axis=0, skipna=True, **kwargs):
140+
def _reduce(self, name, skipna=True, **kwargs):
141141

142142
if skipna:
143143
raise NotImplementedError("decimal does not support skipna=True")
@@ -147,7 +147,7 @@ def _reduce(self, name, axis=0, skipna=True, **kwargs):
147147
except AttributeError:
148148
raise NotImplementedError("decimal does not support "
149149
"the {} operation".format(name))
150-
return op(axis=axis)
150+
return op(axis=0)
151151

152152

153153
DecimalArray._add_arithmetic_ops()

pandas/tests/extension/decimal/test_decimal.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ class Reduce:
136136

137137
def check_reduce(self, s, op_name, skipna):
138138

139-
if skipna or op_name in ['median']:
139+
if skipna or op_name in ['median', 'skew', 'kurt']:
140140
with pytest.raises(NotImplementedError):
141141
getattr(s, op_name)(skipna=skipna)
142142

0 commit comments

Comments
 (0)