diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index c9a8f1c437683..7a7274ca367c0 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -12,13 +12,22 @@ except ImportError: # pragma: no cover _USE_BOTTLENECK = False -def _bottleneck_switch(bn_name, alt, **kwargs): +def _bottleneck_switch(bn_name, alt, zero_value=None, **kwargs): try: bn_func = getattr(bn, bn_name) except (AttributeError, NameError): # pragma: no cover bn_func = None def f(values, axis=None, skipna=True): try: + if zero_value is not None and values.size == 0: + if values.ndim == 1: + return 0 + else: + result_shape = values.shape[:axis] + values.shape[axis + 1:] + result = np.empty(result_shape) + result.fill(0) + return result + if _USE_BOTTLENECK and skipna and values.dtype != np.object_: result = bn_func(values, axis=axis, **kwargs) # prefer to treat inf/-inf as NA @@ -168,7 +177,7 @@ def nanargmin(values, axis=None, skipna=True): result = _maybe_arg_null_out(result, axis, mask, skipna) return result -nansum = _bottleneck_switch('nansum', _nansum) +nansum = _bottleneck_switch('nansum', _nansum, zero_value=0) nanmean = _bottleneck_switch('nanmean', _nanmean) nanmedian = _bottleneck_switch('nanmedian', _nanmedian) nanvar = _bottleneck_switch('nanvar', _nanvar, ddof=1) diff --git a/pandas/tests/test_series.py b/pandas/tests/test_series.py index 4134e59fcfcc2..349c91dac78b8 100644 --- a/pandas/tests/test_series.py +++ b/pandas/tests/test_series.py @@ -162,6 +162,20 @@ def test_comparisons(self): assert_almost_equal(result, expected) + def test_sum_zero(self): + arr = np.array([]) + self.assert_(nanops.nansum(arr) == 0) + + arr = np.empty((10, 0)) + self.assert_((nanops.nansum(arr, axis=1) == 0).all()) + + # GH #844 + s = Series([], index=[]) + self.assert_(s.sum() == 0) + + df = DataFrame(np.empty((10, 0))) + self.assert_((df.sum(1) == 0).all()) + class SafeForSparse(object): pass