summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/release/2.0.0-notes.rst6
-rw-r--r--numpy/core/src/multiarray/calculation.c2
-rw-r--r--numpy/core/src/multiarray/scalarapi.c16
-rw-r--r--numpy/core/src/umath/ufunc_object.c23
-rw-r--r--numpy/core/tests/test_maskna.py56
5 files changed, 80 insertions, 23 deletions
diff --git a/doc/release/2.0.0-notes.rst b/doc/release/2.0.0-notes.rst
index f36889d62..195a24d01 100644
--- a/doc/release/2.0.0-notes.rst
+++ b/doc/release/2.0.0-notes.rst
@@ -22,8 +22,10 @@ What works with NA:
* All element-wise ufuncs.
* UFunc.reduce methods, with a new skipna parameter.
* Array methods:
- + ndarray.clip
- + ndarray.conjugate,
+ + ndarray.clip, ndarray.min, ndarray.max, ndarray.sum, ndarray.prod,
+
+
+ ndarray.conjugate
What doesn't work with NA:
* Fancy indexing, such as with lists and partial boolean masks.
diff --git a/numpy/core/src/multiarray/calculation.c b/numpy/core/src/multiarray/calculation.c
index 9ddbc4b89..b879d0981 100644
--- a/numpy/core/src/multiarray/calculation.c
+++ b/numpy/core/src/multiarray/calculation.c
@@ -152,7 +152,7 @@ PyArray_ArgMin(PyArrayObject *ap, int axis, PyArrayObject *out)
if (PyArray_ISFLEXIBLE(ap)) {
PyErr_SetString(PyExc_TypeError,
- "argmax is unsupported for this type");
+ "argmin is unsupported for this type");
return NULL;
}
else if (PyArray_ISUNSIGNED(ap)) {
diff --git a/numpy/core/src/multiarray/scalarapi.c b/numpy/core/src/multiarray/scalarapi.c
index 2b118a5bd..1efee519b 100644
--- a/numpy/core/src/multiarray/scalarapi.c
+++ b/numpy/core/src/multiarray/scalarapi.c
@@ -424,7 +424,7 @@ PyArray_DescrFromTypeObject(PyObject *type)
/* if it's a builtin type, then use the typenumber */
typenum = _typenum_fromtypeobj(type,1);
- if (typenum != PyArray_NOTYPE) {
+ if (typenum != NPY_NOTYPE) {
new = PyArray_DescrFromType(typenum);
return new;
}
@@ -433,24 +433,24 @@ PyArray_DescrFromTypeObject(PyObject *type)
if ((type == (PyObject *) &PyNumberArrType_Type) ||
(type == (PyObject *) &PyInexactArrType_Type) ||
(type == (PyObject *) &PyFloatingArrType_Type)) {
- typenum = PyArray_DOUBLE;
+ typenum = NPY_DOUBLE;
}
else if (type == (PyObject *)&PyComplexFloatingArrType_Type) {
- typenum = PyArray_CDOUBLE;
+ typenum = NPY_CDOUBLE;
}
else if ((type == (PyObject *)&PyIntegerArrType_Type) ||
(type == (PyObject *)&PySignedIntegerArrType_Type)) {
- typenum = PyArray_LONG;
+ typenum = NPY_LONG;
}
else if (type == (PyObject *) &PyUnsignedIntegerArrType_Type) {
- typenum = PyArray_ULONG;
+ typenum = NPY_ULONG;
}
else if (type == (PyObject *) &PyCharacterArrType_Type) {
- typenum = PyArray_STRING;
+ typenum = NPY_STRING;
}
else if ((type == (PyObject *) &PyGenericArrType_Type) ||
(type == (PyObject *) &PyFlexibleArrType_Type)) {
- typenum = PyArray_VOID;
+ typenum = NPY_VOID;
}
if (typenum != PyArray_NOTYPE) {
@@ -464,7 +464,7 @@ PyArray_DescrFromTypeObject(PyObject *type)
/* Do special thing for VOID sub-types */
if (PyType_IsSubtype((PyTypeObject *)type, &PyVoidArrType_Type)) {
- new = PyArray_DescrNewFromType(PyArray_VOID);
+ new = PyArray_DescrNewFromType(NPY_VOID);
conv = _arraydescr_fromobj(type);
if (conv) {
new->fields = conv->fields;
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c
index 8ab632d5b..09360a8d2 100644
--- a/numpy/core/src/umath/ufunc_object.c
+++ b/numpy/core/src/umath/ufunc_object.c
@@ -2506,7 +2506,7 @@ get_masked_binary_op_function(PyUFuncObject *self, PyArrayObject *arr,
NpyAuxData **out_innerloopdata)
{
int i, retcode;
- PyArrayObject *op[3] = {arr, arr, arr};
+ PyArrayObject *op[3] = {arr, arr, NULL};
PyArray_Descr *dtype[3] = {NULL, NULL, NULL};
PyObject *type_tup = NULL;
@@ -2521,14 +2521,17 @@ get_masked_binary_op_function(PyUFuncObject *self, PyArrayObject *arr,
if (otype_dtype == NULL) {
return -1;
}
- type_tup = Py_BuildValue("(N)", otype_dtype);
+ Py_INCREF(otype_dtype);
+ Py_INCREF(otype_dtype);
+ type_tup = Py_BuildValue("(NNN)",
+ otype_dtype, otype_dtype, otype_dtype);
if (type_tup == NULL) {
return -1;
}
}
/* Use the type resolution function to find our loop */
- retcode = self->type_resolution_masked_function(self, NPY_SAFE_CASTING,
+ retcode = self->type_resolution_masked_function(self, NPY_SAME_KIND_CASTING,
op, type_tup, dtype,
out_innerloop, out_innerloopdata);
Py_XDECREF(type_tup);
@@ -2991,7 +2994,7 @@ PyUFunc_Reduce(PyUFuncObject *self, PyArrayObject *arr, PyArrayObject *out,
PyErr_SetString(PyExc_ValueError,
"Cannot assign NA value to an array which "
"does not support NAs");
- goto fail;
+ return NULL;
}
else {
use_maskna = 0;
@@ -3032,12 +3035,12 @@ PyUFunc_Reduce(PyUFuncObject *self, PyArrayObject *arr, PyArrayObject *out,
}
}
if (retcode < 0) {
- PyArray_Descr *dtype = PyArray_DescrFromType(otype);
- PyErr_Format(PyExc_ValueError,
- "could not find a matching type for %s.reduce, "
- "requested type has type code '%c'",
- ufunc_name, dtype ? dtype->type : '-');
- Py_XDECREF(dtype);
+ //PyArray_Descr *dtype = PyArray_DescrFromType(otype);
+ //PyErr_Format(PyExc_ValueError,
+ // "could not find a matching type for %s.reduce, "
+ // "requested type has type code '%c'",
+ // ufunc_name, dtype ? dtype->type : '-');
+ //Py_XDECREF(dtype);
return NULL;
}
diff --git a/numpy/core/tests/test_maskna.py b/numpy/core/tests/test_maskna.py
index cd0830ad7..4a04123e7 100644
--- a/numpy/core/tests/test_maskna.py
+++ b/numpy/core/tests/test_maskna.py
@@ -735,8 +735,8 @@ def test_array_maskna_clip_method():
assert_equal(np.isna(res), [0,1,0,0,1,0])
assert_equal(res[~np.isna(res)], [4, 7, 4, 7])
-def test_array_maskna_max_min_methods():
- # ndarray.max, ndarray.min
+def test_array_maskna_max_min_ptp_methods():
+ # ndarray.max, ndarray.min, ndarray.ptp
a = np.array([[2, np.NA, 10],
[4, 8, 7],
[12, 4, np.NA]], maskna=True)
@@ -757,6 +757,58 @@ def test_array_maskna_max_min_methods():
assert_equal(np.isna(res), [1,0,1])
assert_equal(res[~np.isna(res)], [4])
+ res = a.ptp(axis=0)
+ assert_equal(np.isna(res), [0,1,1])
+ assert_equal(res[~np.isna(res)], [10])
+
+ res = a.ptp(axis=-1)
+ assert_equal(np.isna(res), [1,0,1])
+ assert_equal(res[~np.isna(res)], [4])
+
+def test_array_maskna_sum_prod_methods():
+ # ndarray.sum, ndarray.prod
+ a = np.array([[2, np.NA, 10],
+ [4, 8, 7],
+ [12, 4, np.NA]], maskna=True)
+
+ res = a.sum(axis=0)
+ assert_equal(np.isna(res), [0,1,1])
+ assert_equal(res[~np.isna(res)], [18])
+
+ res = a.sum(axis=-1)
+ assert_equal(np.isna(res), [1,0,1])
+ assert_equal(res[~np.isna(res)], [19])
+
+ res = a.prod(axis=0)
+ assert_equal(np.isna(res), [0,1,1])
+ assert_equal(res[~np.isna(res)], [2*4*12])
+
+ res = a.prod(axis=-1)
+ assert_equal(np.isna(res), [1,0,1])
+ assert_equal(res[~np.isna(res)], [4*8*7])
+
+def test_array_maskna_std_mean_methods():
+ # ndarray.std, ndarray.mean
+ a = np.array([[2, np.NA, 10],
+ [4, 8, 7],
+ [12, 4, np.NA]], maskna=True)
+
+ res = a.mean(axis=0)
+ assert_equal(np.isna(res), [0,1,1])
+ assert_equal(res[~np.isna(res)], [np.array([2,4,12]).mean()])
+
+ res = a.mean(axis=-1)
+ assert_equal(np.isna(res), [1,0,1])
+ assert_equal(res[~np.isna(res)], [np.array([4,8,7]).mean()])
+
+ res = a.std(axis=0)
+ assert_equal(np.isna(res), [0,1,1])
+ assert_equal(res[~np.isna(res)], [np.array([2,4,12]).std()])
+
+ res = a.std(axis=-1)
+ assert_equal(np.isna(res), [1,0,1])
+ assert_equal(res[~np.isna(res)], [np.array([4,8,7]).std()])
+
def test_array_maskna_conjugate_method():
# ndarray.conjugate
a = np.array([1j, 2+4j, np.NA, 2-1.5j, np.NA], maskna=True)