Repository: numpy/numpy

Issue:
MaskedArray.trace() inconsistent with ndarray.trace() for arrays with ndim>2
The `trace` method for a masked array with more than 2 dimensions does not appear to respect the `axis1` and `axis2` methods.  In fact, for a 3-dimensional array, `MaskedArray.trace` does not return an array as `ndarray.trace` does, but appears to return the sum of the relevant array.  See the code sample below.

```
In [782]: A = arange(2*4*4).reshape(2,4,4)

In [783]: A.trace(axis1=1, axis2=2)
Out[783]: array([30, 94])

In [784]: Am = ma.masked_array(A, False)

In [785]: Am.trace(axis1=1, axis2=2)
Out[785]: 124.0
```



Discussion:
I think it is actually returning the sum of the diagonal, see [this](https://github.com/numpy/numpy/blob/master/numpy/ma/core.py#L4518). But I have no idea why this is done, also the `ma.trace` function would work just fine if the mask was `np.ma.nomask`. 

```
>>>am = np.ma.masked_array(A,np.ma.nomask)
>>>am.trace(axis1=1,axis2=2)
masked_array(data = [ 30.  94.],
         mask = False,
   fill_value = 1e+20)
```

Hope it helps :)

Still present in 1.14-dev

Resolving patch:
diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py
--- a/numpy/core/fromnumeric.py
+++ b/numpy/core/fromnumeric.py
@@ -1245,13 +1245,13 @@ def diagonal(a, offset=0, axis1=0, axis2=1):
     Returns
     -------
     array_of_diagonals : ndarray
-        If `a` is 2-D and not a matrix, a 1-D array of the same type as `a`
-        containing the diagonal is returned. If `a` is a matrix, a 1-D
+        If `a` is 2-D and not a `matrix`, a 1-D array of the same type as `a`
+        containing the diagonal is returned. If `a` is a `matrix`, a 1-D
         array containing the diagonal is returned in order to maintain
-        backward compatibility.  If the dimension of `a` is greater than
-        two, then an array of diagonals is returned, "packed" from
-        left-most dimension to right-most (e.g., if `a` is 3-D, then the
-        diagonals are "packed" along rows).
+        backward compatibility.
+        If ``a.ndim > 2``, then the dimensions specified by `axis1` and `axis2`
+        are removed, and a new axis inserted at the end corresponding to the
+        diagonal.
 
     Raises
     ------
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -4819,7 +4819,7 @@ def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None):
             return result.astype(dtype)
         else:
             D = self.diagonal(offset=offset, axis1=axis1, axis2=axis2)
-            return D.astype(dtype).filled(0).sum(axis=None, out=out)
+            return D.astype(dtype).filled(0).sum(axis=-1, out=out)
     trace.__doc__ = ndarray.trace.__doc__
 
     def dot(self, b, out=None, strict=False):


Test patch:
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -3550,6 +3550,11 @@ def test_trace(self):
                                             axis=0))
         assert_equal(np.trace(mX), mX.trace())
 
+        # gh-5560
+        arr = np.arange(2*4*4).reshape(2,4,4)
+        m_arr = np.ma.masked_array(arr, False)
+        assert_equal(arr.trace(axis1=1, axis2=2), m_arr.trace(axis1=1, axis2=2))
+
     def test_dot(self):
         # Tests dot on MaskedArrays.
         (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d