Repository: numpy/numpy

Issue:
np.average crashes for 1D decimal object array (now only without weights)
I'm running macOS 10.12.3, Python 3.6.0, and NumPy 1.12.0.

When using the decimal package with NumPy, the arrays are of type 'object'. While most operations are performed flawlessly, calling np.average() with one of these arrays throws an error if weights are not provided (`AttributeError: 'decimal.Decimal' object has no attribute 'dtype'`), and a different error if weights are provided (`AttributeError: 'bool' object has no attribute 'any'`). Contrarily, calling np.mean() executes without error.

The source of the problem in both cases appears to be the assumption that the result of folding the input array results in a standard supported dtype, rather than being based on the operations available to the object type.

Therefore, I suspect that this issue will extend to any types which support the requisite numeric operations but are not natively supported by NumPy.

I resolved the weighted problem for my use case by changing the line `if (scl == 0.0).any()` (line 1138 in `lib/function_base.py`) to check if scl were an array first, and if not then removing the `any()` call, though I don't know if that solution is desirable or acceptable for the purposes of NumPy.

Sample input:
```
import numpy as np                                                              
import decimal as dc                                                            
                                                                                
values = np.array([dc.Decimal(x) for x in range(10)])                           
weights = np.array([dc.Decimal(x) for x in range(10)])                          
weights /= weights.sum()                                                        
                                                                                
print(np.mean(values))                                                          
print(np.average(values, weights=weights))                                      
```

Corresponding output:
```
4.5
Traceback (most recent call last):
  File "bugreport.py", line 9, in <module>
    print(np.average(values, weights=weights))
  File "/usr/local/lib/python3.6/site-packages/numpy/lib/function_base.py", line 1138, in average
    if (scl == 0.0).any():
AttributeError: 'bool' object has no attribute 'any'
```


Discussion:
Yes, this seems like a bug and certainly doesn't reflected the intended behavior as described in the docs. Decimal arrays should be acceptable as arguments for this function.

Resolving patch:
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -1135,7 +1135,7 @@ def average(a, axis=None, weights=None, returned=False):
             wgt = wgt.swapaxes(-1, axis)
 
         scl = wgt.sum(axis=axis, dtype=result_dtype)
-        if (scl == 0.0).any():
+        if np.any(scl == 0.0):
             raise ZeroDivisionError(
                 "Weights sum to zero, can't be normalized")
 


Test patch:
diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py
--- a/numpy/lib/tests/test_function_base.py
+++ b/numpy/lib/tests/test_function_base.py
@@ -3,6 +3,7 @@
 import operator
 import warnings
 import sys
+import decimal
 
 import numpy as np
 from numpy.testing import (
@@ -341,6 +342,12 @@ def test_upcasting(self):
             w = np.array([[1,2],[3,4]], dtype=wt)
             assert_equal(np.average(a, weights=w).dtype, np.dtype(rt))
 
+    def test_object_dtype(self):
+        a = np.array([decimal.Decimal(x) for x in range(10)])
+        w = np.array([decimal.Decimal(1) for _ in range(10)])
+        w /= w.sum()
+        assert_almost_equal(a.mean(0), average(a, weights=w)) 
+
 class TestSelect(TestCase):
     choices = [np.array([1, 2, 3]),
                np.array([4, 5, 6]),