33for missing values.
44"""
55
6+ from typing import Callable
7+
68import numpy as np
79
810from pandas ._libs import missing as libmissing
1113from pandas .core .nanops import check_below_min_count
1214
1315
14- def sum (
15- values : np .ndarray , mask : np .ndarray , skipna : bool = True , min_count : int = 0 ,
16+ def _sumprod (
17+ func : Callable ,
18+ values : np .ndarray ,
19+ mask : np .ndarray ,
20+ skipna : bool = True ,
21+ min_count : int = 0 ,
1622):
1723 """
18- Sum for 1D masked array.
24+ Sum or product for 1D masked array.
1925
2026 Parameters
2127 ----------
28+ func : np.sum or np.prod
2229 values : np.ndarray
2330 Numpy array with the values (can be of any dtype that support the
2431 operation).
@@ -31,23 +38,33 @@ def sum(
3138 ``min_count`` non-NA values are present the result will be NA.
3239 """
3340 if not skipna :
34- if mask .any ():
41+ if mask .any () or check_below_min_count ( values . shape , None , min_count ) :
3542 return libmissing .NA
3643 else :
37- if check_below_min_count (values .shape , None , min_count ):
38- return libmissing .NA
39- return np .sum (values )
44+ return func (values )
4045 else :
4146 if check_below_min_count (values .shape , mask , min_count ):
4247 return libmissing .NA
4348
4449 if _np_version_under1p17 :
45- return np . sum (values [~ mask ])
50+ return func (values [~ mask ])
4651 else :
47- return np .sum (values , where = ~ mask )
52+ return func (values , where = ~ mask )
53+
54+
55+ def sum (values : np .ndarray , mask : np .ndarray , skipna : bool = True , min_count : int = 0 ):
56+ return _sumprod (
57+ np .sum , values = values , mask = mask , skipna = skipna , min_count = min_count
58+ )
4859
4960
50- def _minmax (func , values : np .ndarray , mask : np .ndarray , skipna : bool = True ):
61+ def prod (values : np .ndarray , mask : np .ndarray , skipna : bool = True , min_count : int = 0 ):
62+ return _sumprod (
63+ np .prod , values = values , mask = mask , skipna = skipna , min_count = min_count
64+ )
65+
66+
67+ def _minmax (func : Callable , values : np .ndarray , mask : np .ndarray , skipna : bool = True ):
5168 """
5269 Reduction for 1D masked array.
5370
@@ -63,18 +80,15 @@ def _minmax(func, values: np.ndarray, mask: np.ndarray, skipna: bool = True):
6380 Whether to skip NA.
6481 """
6582 if not skipna :
66- if mask .any ():
83+ if mask .any () or not values .size :
84+ # min/max with empty array raise in numpy, pandas returns NA
6785 return libmissing .NA
6886 else :
69- if values .size :
70- return func (values )
71- else :
72- # min/max with empty array raise in numpy, pandas returns NA
73- return libmissing .NA
87+ return func (values )
7488 else :
7589 subset = values [~ mask ]
7690 if subset .size :
77- return func (values [ ~ mask ] )
91+ return func (subset )
7892 else :
7993 # min/max with empty array raise in numpy, pandas returns NA
8094 return libmissing .NA
0 commit comments