summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorMark Wiebe <mwiebe@enthought.com>2011-08-04 16:35:54 -0500
committerCharles Harris <charlesr.harris@gmail.com>2011-08-27 07:26:52 -0600
commit9061b0e9899b712c7de88d908adc3ae32155b101 (patch)
treed7725d2d8f8f9f23508d783724e2dd99f9ca8885 /numpy
parent1992ee21cf1b87e9e5a48beff66ebc8fc8c381f0 (diff)
downloadnumpy-9061b0e9899b712c7de88d908adc3ae32155b101.tar.gz
ENH: missingdata: Add skipna parameters to sum, prod, etc
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/fromnumeric.py81
-rw-r--r--numpy/core/src/multiarray/ctors.c12
-rw-r--r--numpy/core/tests/test_maskna.py45
3 files changed, 92 insertions, 46 deletions
diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py
index c7e390c73..8825dc6b7 100644
--- a/numpy/core/fromnumeric.py
+++ b/numpy/core/fromnumeric.py
@@ -1376,7 +1376,7 @@ def clip(a, a_min, a_max, out=None):
return clip(a_min, a_max, out)
-def sum(a, axis=None, dtype=None, out=None):
+def sum(a, axis=None, dtype=None, out=None, skipna=False):
"""
Sum of array elements over a given axis.
@@ -1406,6 +1406,9 @@ def sum(a, axis=None, dtype=None, out=None):
(the shape of `a` with `axis` removed, i.e.,
``numpy.delete(a.shape, axis)``). Its type is preserved. See
`doc.ufuncs` (Section "Output arguments") for more details.
+ skipna : bool, optional
+ If this is set to True, skips any NA values during summation
+ instead of propagating them.
Returns
-------
@@ -1459,10 +1462,13 @@ def sum(a, axis=None, dtype=None, out=None):
try:
sum = a.sum
except AttributeError:
- return um.add.reduce(a, axis=axis, dtype=dtype, out=out)
+ return um.add.reduce(a, axis=axis, dtype=dtype,
+ out=out, skipna=skipna)
+ # NOTE: Dropping the skipna parameter here...
return sum(axis=axis, dtype=dtype, out=out)
else:
- return um.add.reduce(a, axis=axis, dtype=dtype, out=out)
+ return um.add.reduce(a, axis=axis, dtype=dtype,
+ out=out, skipna=skipna)
def product (a, axis=None, dtype=None, out=None):
"""
@@ -1501,7 +1507,7 @@ def alltrue (a, axis=None, out=None):
"""
return um.logical_and.reduce(a, axis=axis, out=out)
-def any(a,axis=None, out=None):
+def any(a, axis=None, out=None, skipna=False):
"""
Test whether any array element along a given axis evaluates to True.
@@ -1527,6 +1533,9 @@ def any(a,axis=None, out=None):
(e.g., if it is of type float, then it will remain so, returning
1.0 for True and 0.0 for False, regardless of the type of `a`).
See `doc.ufuncs` (Section "Output arguments") for details.
+ skipna : bool, optional
+ If this is set to True, skips any NA values during summation
+ instead of propagating them.
Returns
-------
@@ -1570,9 +1579,9 @@ def any(a,axis=None, out=None):
(191614240, 191614240)
"""
- return um.logical_or.reduce(a, axis=axis, out=out)
+ return um.logical_or.reduce(a, axis=axis, out=out, skipna=skipna)
-def all(a,axis=None, out=None):
+def all(a, axis=None, out=None, skipna=False):
"""
Test whether all array elements along a given axis evaluate to True.
@@ -1596,6 +1605,9 @@ def all(a,axis=None, out=None):
type is preserved (e.g., if ``dtype(out)`` is float, the result
will consist of 0.0's and 1.0's). See `doc.ufuncs` (Section
"Output arguments") for more details.
+ skipna : bool, optional
+ If this is set to True, skips any NA values during summation
+ instead of propagating them.
Returns
-------
@@ -1634,7 +1646,7 @@ def all(a,axis=None, out=None):
(28293632, 28293632, array([ True], dtype=bool))
"""
- return um.logical_and.reduce(a, axis=axis, out=out)
+ return um.logical_and.reduce(a, axis=axis, out=out, skipna=skipna)
def cumsum (a, axis=None, dtype=None, out=None):
"""
@@ -1767,7 +1779,7 @@ def ptp(a, axis=None, out=None):
return ptp(axis, out)
-def amax(a, axis=None, out=None):
+def amax(a, axis=None, out=None, skipna=False):
"""
Return the maximum of an array or maximum along an axis.
@@ -1781,6 +1793,9 @@ def amax(a, axis=None, out=None):
Alternate output array in which to place the result. Must be of
the same shape and buffer length as the expected output. See
`doc.ufuncs` (Section "Output arguments") for more details.
+ skipna : bool, optional
+ If this is set to True, skips any NA values during summation
+ instead of propagating them.
Returns
-------
@@ -1822,14 +1837,19 @@ def amax(a, axis=None, out=None):
4.0
"""
- try:
- amax = a.max
- except AttributeError:
- return _wrapit(a, 'max', axis, out)
- return amax(axis, out)
-
+ if not (type(a) is mu.ndarray):
+ try:
+ amax = a.max
+ except AttributeError:
+ return um.maximum.reduce(a, axis=axis,
+ out=out, skipna=skipna)
+ # NOTE: Dropping the skipna parameter
+ return amax(axis=axis, out=out)
+ else:
+ return um.maximum.reduce(a, axis=axis,
+ out=out, skipna=skipna)
-def amin(a, axis=None, out=None):
+def amin(a, axis=None, out=None, skipna=False):
"""
Return the minimum of an array or minimum along an axis.
@@ -1843,6 +1863,9 @@ def amin(a, axis=None, out=None):
Alternative output array in which to place the result. Must
be of the same shape and buffer length as the expected output.
See `doc.ufuncs` (Section "Output arguments") for more details.
+ skipna : bool, optional
+ If this is set to True, skips any NA values during summation
+ instead of propagating them.
Returns
-------
@@ -1884,12 +1907,17 @@ def amin(a, axis=None, out=None):
0.0
"""
- try:
- amin = a.min
- except AttributeError:
- return _wrapit(a, 'min', axis, out)
- return amin(axis, out)
-
+ if not (type(a) is mu.ndarray):
+ try:
+ amin = a.min
+ except AttributeError:
+ return um.minimum.reduce(a, axis=axis,
+ out=out, skipna=skipna)
+ # NOTE: Dropping the skipna parameter
+ return amin(axis=axis, out=out)
+ else:
+ return um.minimum.reduce(a, axis=axis,
+ out=out, skipna=skipna)
def alen(a):
"""
@@ -1924,7 +1952,7 @@ def alen(a):
return len(array(a,ndmin=1))
-def prod(a, axis=None, dtype=None, out=None):
+def prod(a, axis=None, dtype=None, out=None, skipna=False):
"""
Return the product of array elements over a given axis.
@@ -1952,6 +1980,9 @@ def prod(a, axis=None, dtype=None, out=None):
Alternative output array in which to place the result. It must have
the same shape as the expected output, but the type of the
output values will be cast if necessary.
+ skipna : bool, optional
+ If this is set to True, skips any NA values during summation
+ instead of propagating them.
Returns
-------
@@ -2009,10 +2040,12 @@ def prod(a, axis=None, dtype=None, out=None):
try:
prod = a.prod
except AttributeError:
- return um.multiply.reduce(a, axis=axis, dtype=dtype, out=out)
+ return um.multiply.reduce(a, axis=axis, dtype=dtype,
+ out=out, skipna=skipna)
return prod(axis=axis, dtype=dtype, out=out)
else:
- return um.multiply.reduce(a, axis=axis, dtype=dtype, out=out)
+ return um.multiply.reduce(a, axis=axis, dtype=dtype,
+ out=out, skipna=skipna)
def cumprod(a, axis=None, dtype=None, out=None):
"""
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c
index ac3a6648b..4d0f3378c 100644
--- a/numpy/core/src/multiarray/ctors.c
+++ b/numpy/core/src/multiarray/ctors.c
@@ -276,12 +276,12 @@ _unaligned_strided_byte_copy(char *dst, npy_intp outstrides, char *src,
char *tout = dst;
char *tin = src;
-#define _COPY_N_SIZE(size) \
- for(i=0; i<N; i++) { \
- memcpy(tout, tin, size); \
- tin += instrides; \
- tout += outstrides; \
- } \
+#define _COPY_N_SIZE(size) \
+ for(i=0; i<N; i++) { \
+ memcpy(tout, tin, size); \
+ tin += instrides; \
+ tout += outstrides; \
+ } \
return
switch(elsize) {
diff --git a/numpy/core/tests/test_maskna.py b/numpy/core/tests/test_maskna.py
index a7127868a..1bde3c691 100644
--- a/numpy/core/tests/test_maskna.py
+++ b/numpy/core/tests/test_maskna.py
@@ -583,82 +583,95 @@ def test_maskna_ufunc_1D():
assert_(c.flags.maskna)
#assert_equal(c, [0,2,4])
+def test_maskna_ufunc_sum_1D():
+ check_maskna_ufunc_sum_1D(np.sum)
+
def test_maskna_ufunc_add_reduce_1D():
+ check_maskna_ufunc_sum_1D(np.add.reduce)
+
+def check_maskna_ufunc_sum_1D(sum_func):
a = np.arange(3.0, maskna=True)
b = np.array(0.5)
c_orig = np.array(0.5)
c = c_orig.view(maskna=True)
# Since 'a' has no NA values, this should work
- np.add.reduce(a, out=b)
+ sum_func(a, out=b)
assert_equal(b, 3.0)
- np.add.reduce(a, skipna=True, out=b)
+ b[...] = 7
+ sum_func(a, skipna=True, out=b)
assert_equal(b, 3.0)
- ret = np.add.reduce(a)
+ ret = sum_func(a)
assert_equal(ret, 3.0)
- ret = np.add.reduce(a, skipna=True)
+ ret = sum_func(a, skipna=True)
assert_equal(ret, 3.0)
# With an NA value, the reduce should throw with the non-NA output param
a[1] = np.NA
- assert_raises(ValueError, np.add.reduce, a, out=b)
+ assert_raises(ValueError, sum_func, a, out=b)
# With an NA value, the output parameter can still be an NA-array
c_orig[...] = 0.5
- np.add.reduce(a, out=c)
+ sum_func(a, out=c)
assert_equal(c_orig, 0.5)
assert_(np.isna(c))
# Should not touch the out= element when assigning NA
b[...] = 1.0
d = b.view(maskna=True)
- np.add.reduce(a, out=d)
+ sum_func(a, out=d)
assert_(np.isna(d))
assert_equal(b, 1.0)
# Without an output parameter, return NA
- ret = np.add.reduce(a)
+ ret = sum_func(a)
assert_(np.isna(ret))
# With 'skipna=True'
- ret = np.add.reduce(a, skipna=True)
+ ret = sum_func(a, skipna=True)
assert_equal(ret, 2.0)
# With 'skipna=True', and out= parameter
b[...] = 0.5
- np.add.reduce(a, skipna=True, out=b)
+ sum_func(a, skipna=True, out=b)
assert_equal(b, 2.0)
# With 'skipna=True', and out= parameter with a mask
c[...] = 0.5
c[...] = np.NA
- np.add.reduce(a, skipna=True, out=c)
+ sum_func(a, skipna=True, out=c)
assert_(not np.isna(c))
assert_equal(c, 2.0)
+def test_ufunc_max_1D():
+ check_ufunc_max_1D(np.max)
+
def test_ufunc_maximum_reduce_1D():
+ check_ufunc_max_1D(np.maximum.reduce)
+
+def check_ufunc_max_1D(max_func):
a_orig = np.array([0, 3, 2, 10, -1, 5, 7, -2])
a = a_orig.view(maskna=True)
# Straightforward reduce with no NAs
- b = np.maximum.reduce(a)
+ b = max_func(a)
assert_equal(b, 10)
# Set the biggest value to NA
a[3] = np.NA
- b = np.maximum.reduce(a)
+ b = max_func(a)
assert_(np.isna(b))
# Skip the NA
- b = np.maximum.reduce(a, skipna=True)
+ b = max_func(a, skipna=True)
assert_(not b.flags.maskna)
assert_(not np.isna(b))
assert_equal(b, 7)
# Set the first value to NA
a[0] = np.NA
- b = np.maximum.reduce(a, skipna=True)
+ b = max_func(a, skipna=True)
assert_(not b.flags.maskna)
assert_(not np.isna(b))
assert_equal(b, 7)
@@ -666,7 +679,7 @@ def test_ufunc_maximum_reduce_1D():
# Set all the values to NA - should raise the same error as
# for an empty array
a[...] = np.NA
- assert_raises(ValueError, np.maximum.reduce, a, skipna=True)
+ assert_raises(ValueError, max_func, a, skipna=True)
if __name__ == "__main__":
run_module_suite()