3
3
for missing values.
4
4
"""
5
5
6
+ from typing import Callable
7
+
6
8
import numpy as np
7
9
8
10
from pandas ._libs import missing as libmissing
11
13
from pandas .core .nanops import check_below_min_count
12
14
13
15
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 ,
16
22
):
17
23
"""
18
- Sum for 1D masked array.
24
+ Sum or product for 1D masked array.
19
25
20
26
Parameters
21
27
----------
28
+ func : np.sum or np.prod
22
29
values : np.ndarray
23
30
Numpy array with the values (can be of any dtype that support the
24
31
operation).
@@ -31,23 +38,33 @@ def sum(
31
38
``min_count`` non-NA values are present the result will be NA.
32
39
"""
33
40
if not skipna :
34
- if mask .any ():
41
+ if mask .any () or check_below_min_count ( values . shape , None , min_count ) :
35
42
return libmissing .NA
36
43
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 )
40
45
else :
41
46
if check_below_min_count (values .shape , mask , min_count ):
42
47
return libmissing .NA
43
48
44
49
if _np_version_under1p17 :
45
- return np . sum (values [~ mask ])
50
+ return func (values [~ mask ])
46
51
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
+ )
48
59
49
60
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 ):
51
68
"""
52
69
Reduction for 1D masked array.
53
70
@@ -63,18 +80,15 @@ def _minmax(func, values: np.ndarray, mask: np.ndarray, skipna: bool = True):
63
80
Whether to skip NA.
64
81
"""
65
82
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
67
85
return libmissing .NA
68
86
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 )
74
88
else :
75
89
subset = values [~ mask ]
76
90
if subset .size :
77
- return func (values [ ~ mask ] )
91
+ return func (subset )
78
92
else :
79
93
# min/max with empty array raise in numpy, pandas returns NA
80
94
return libmissing .NA
0 commit comments