@@ -7310,7 +7310,8 @@ def _add_numeric_operations(cls):
7310
7310
@Substitution (outname = 'mad' ,
7311
7311
desc = "Return the mean absolute deviation of the values "
7312
7312
"for the requested axis" ,
7313
- name1 = name , name2 = name2 , axis_descr = axis_descr )
7313
+ name1 = name , name2 = name2 , axis_descr = axis_descr ,
7314
+ empty_is_na = '' )
7314
7315
@Appender (_num_doc )
7315
7316
def mad (self , axis = None , skipna = None , level = None ):
7316
7317
if skipna is None :
@@ -7351,7 +7352,7 @@ def mad(self, axis=None, skipna=None, level=None):
7351
7352
@Substitution (outname = 'compounded' ,
7352
7353
desc = "Return the compound percentage of the values for "
7353
7354
"the requested axis" , name1 = name , name2 = name2 ,
7354
- axis_descr = axis_descr )
7355
+ axis_descr = axis_descr , empty_is_na = '' )
7355
7356
@Appender (_num_doc )
7356
7357
def compound (self , axis = None , skipna = None , level = None ):
7357
7358
if skipna is None :
@@ -7375,10 +7376,11 @@ def compound(self, axis=None, skipna=None, level=None):
7375
7376
lambda y , axis : np .maximum .accumulate (y , axis ), "max" ,
7376
7377
- np .inf , np .nan )
7377
7378
7378
- cls .sum = _make_stat_function (
7379
+ cls .sum = _make_empty_stat_function (
7379
7380
cls , 'sum' , name , name2 , axis_descr ,
7380
7381
'Return the sum of the values for the requested axis' ,
7381
- nanops .nansum )
7382
+ nanops .nansum ,
7383
+ empty_is_na = False )
7382
7384
cls .mean = _make_stat_function (
7383
7385
cls , 'mean' , name , name2 , axis_descr ,
7384
7386
'Return the mean of the values for the requested axis' ,
@@ -7394,10 +7396,11 @@ def compound(self, axis=None, skipna=None, level=None):
7394
7396
"by N-1\n " ,
7395
7397
nanops .nankurt )
7396
7398
cls .kurtosis = cls .kurt
7397
- cls .prod = _make_stat_function (
7399
+ cls .prod = _make_empty_stat_function (
7398
7400
cls , 'prod' , name , name2 , axis_descr ,
7399
7401
'Return the product of the values for the requested axis' ,
7400
- nanops .nanprod )
7402
+ nanops .nanprod ,
7403
+ empty_is_na = False )
7401
7404
cls .product = cls .prod
7402
7405
cls .median = _make_stat_function (
7403
7406
cls , 'median' , name , name2 , axis_descr ,
@@ -7520,14 +7523,14 @@ def _doc_parms(cls):
7520
7523
----------
7521
7524
axis : %(axis_descr)s
7522
7525
skipna : boolean, default True
7523
- Exclude NA/null values. If an entire row/column is NA or empty, the result
7524
- will be NA
7526
+ Exclude NA/null values before computing the result.
7525
7527
level : int or level name, default None
7526
7528
If the axis is a MultiIndex (hierarchical), count along a
7527
7529
particular level, collapsing into a %(name1)s
7528
7530
numeric_only : boolean, default None
7529
7531
Include only float, int, boolean columns. If None, will attempt to use
7530
- everything, then use only numeric data. Not implemented for Series.
7532
+ everything, then use only numeric data. Not implemented for
7533
+ Series.%(empty_is_na)s
7531
7534
7532
7535
Returns
7533
7536
-------
@@ -7584,7 +7587,7 @@ def _doc_parms(cls):
7584
7587
axis : %(axis_descr)s
7585
7588
skipna : boolean, default True
7586
7589
Exclude NA/null values. If an entire row/column is NA, the result
7587
- will be NA
7590
+ will be NA.
7588
7591
7589
7592
Returns
7590
7593
-------
@@ -7598,16 +7601,45 @@ def _doc_parms(cls):
7598
7601
7599
7602
"""
7600
7603
7604
+ _empty_is_na_doc = """
7605
+ empty_is_na : bool, default False
7606
+ The result of operating on an empty array should be NA. The default
7607
+ behavior is for the sum of an empty array to be 0, and the product
7608
+ of an empty array to be 1.
7609
+
7610
+ When ``skipna=True``, "empty" refers to whether or not the array
7611
+ is empty after removing NAs. So operating on an all-NA array with
7612
+ ``skipna=True`` will be NA when ``empty_is_na`` is True.
7613
+ """
7614
+
7615
+
7616
+ def _make_empty_stat_function (cls , name , name1 , name2 , axis_descr , desc , f ,
7617
+ empty_is_na = False ):
7618
+ @Substitution (outname = name , desc = desc , name1 = name1 , name2 = name2 ,
7619
+ axis_descr = axis_descr , empty_is_na = _empty_is_na_doc )
7620
+ @Appender (_num_doc )
7621
+ def stat_func (self , axis = None , skipna = True , level = None , numeric_only = None ,
7622
+ empty_is_na = empty_is_na , ** kwargs ):
7623
+ nv .validate_stat_func (tuple (), kwargs , fname = name )
7624
+ if axis is None :
7625
+ axis = self ._stat_axis_number
7626
+ if level is not None :
7627
+ return self ._agg_by_level (name , axis = axis , level = level ,
7628
+ skipna = skipna , empty_is_na = empty_is_na )
7629
+ return self ._reduce (f , name , axis = axis , skipna = skipna ,
7630
+ numeric_only = numeric_only ,
7631
+ empty_is_na = empty_is_na )
7632
+
7633
+ return set_function_name (stat_func , name , cls )
7634
+
7601
7635
7602
7636
def _make_stat_function (cls , name , name1 , name2 , axis_descr , desc , f ):
7603
7637
@Substitution (outname = name , desc = desc , name1 = name1 , name2 = name2 ,
7604
- axis_descr = axis_descr )
7638
+ axis_descr = axis_descr , empty_is_na = '' )
7605
7639
@Appender (_num_doc )
7606
- def stat_func (self , axis = None , skipna = None , level = None , numeric_only = None ,
7640
+ def stat_func (self , axis = None , skipna = True , level = None , numeric_only = None ,
7607
7641
** kwargs ):
7608
7642
nv .validate_stat_func (tuple (), kwargs , fname = name )
7609
- if skipna is None :
7610
- skipna = True
7611
7643
if axis is None :
7612
7644
axis = self ._stat_axis_number
7613
7645
if level is not None :
0 commit comments