diff options
-rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 14 | ||||
-rw-r--r-- | numpy/core/tests/test_ufunc.py | 28 |
2 files changed, 36 insertions, 6 deletions
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c index 554ec6f51..93f63038a 100644 --- a/numpy/core/src/umath/ufunc_object.c +++ b/numpy/core/src/umath/ufunc_object.c @@ -2831,10 +2831,24 @@ PyUFunc_Reduce(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *out, case PyUFunc_Zero: assign_identity = &assign_reduce_identity_zero; reorderable = 1; + /* + * The identity for a dynamic dtype like + * object arrays can't be used in general + */ + if (PyArray_ISOBJECT(arr) && PyArray_SIZE(arr) != 0) { + assign_identity = NULL; + } break; case PyUFunc_One: assign_identity = &assign_reduce_identity_one; reorderable = 1; + /* + * The identity for a dynamic dtype like + * object arrays can't be used in general + */ + if (PyArray_ISOBJECT(arr) && PyArray_SIZE(arr) != 0) { + assign_identity = NULL; + } break; case PyUFunc_None: reorderable = 0; diff --git a/numpy/core/tests/test_ufunc.py b/numpy/core/tests/test_ufunc.py index 44f402ac7..eb1da6676 100644 --- a/numpy/core/tests/test_ufunc.py +++ b/numpy/core/tests/test_ufunc.py @@ -507,13 +507,29 @@ class TestUfunc(TestCase): assert_equal(np.logical_or.reduce(a), 3) assert_equal(np.logical_and.reduce(a), None) + def test_object_array_reduction(self): + # Reductions on object arrays + a = np.array(['a', 'b', 'c'], dtype=object) + assert_equal(np.sum(a), 'abc') + assert_equal(np.max(a), 'c') + assert_equal(np.min(a), 'a') + a = np.array([True, False, True], dtype=object) + assert_equal(np.sum(a), 2) + assert_equal(np.prod(a), 0) + assert_equal(np.any(a), True) + assert_equal(np.all(a), False) + assert_equal(np.max(a), True) + assert_equal(np.min(a), False) + def test_zerosize_reduction(self): - assert_equal(np.sum([]), 0) - assert_equal(np.prod([]), 1) - assert_equal(np.any([]), False) - assert_equal(np.all([]), True) - assert_raises(ValueError, np.max, []) - assert_raises(ValueError, np.min, []) + # Test with default dtype and object dtype + for a in [[], np.array([], dtype=object)]: + assert_equal(np.sum(a), 0) + assert_equal(np.prod(a), 1) + assert_equal(np.any(a), False) + assert_equal(np.all(a), True) + assert_raises(ValueError, np.max, a) + assert_raises(ValueError, np.min, a) def test_axis_out_of_bounds(self): a = np.array([False, False]) |