Matrix behavior

If X is a NumPy object matrix, why does it np.trace(X)return a scalar (as expected) but X.trace()return an object 1x1 matrix?

>>> X = np.matrix([[1, 2], [3, 4]])
>>> np.trace(X)
5
>>> X.trace()
matrix([[5]])   # Why not just 5, which would be more useful?

I am using NumPy 1.7.1 but cannot see anything in the release notes for 1.8 to suggest that something has changed.

+3
source share
2 answers

Because it is X.traceencoded in this way! The documentation matrixreads:

A matrix is ​​a specialized two-dimensional array that preserves its two-dimensional nature through operations.

np.traceencoded as (using ndarray.trace):

return asarray(a).trace(offset, axis1, axis2, dtype, out)

It’s harder to keep track of how matrix tracing is evaluated. But looking at https://github.com/numpy/numpy/blob/master/numpy/matrixlib/defmatrix.py

, :

np.asmatrix(X.A.trace())

sum :

return N.ndarray.sum(self, axis, dtype, out, keepdims=True)._collapse(axis)

mean, prod .. . _collapse , axis - None. trace, , , __array_finalize__. , trace matrix .

, :

X.A.trace()
X.diagonal().sum()
X.trace()._collapse(None)
+2
def __array_finalize__(self, obj):
    self._getitem = False
    if (isinstance(obj, matrix) and obj._getitem): return
    ndim = self.ndim
    if (ndim == 2):
        return
    if (ndim > 2):
        newshape = tuple([x for x in self.shape if x > 1])
        ndim = len(newshape)
        if ndim == 2:
            self.shape = newshape
            return
        elif (ndim > 2):
            raise ValueError("shape too large to be a matrix.")
    else:
        newshape = self.shape
    if ndim == 0:
        self.shape = (1, 1)
    elif ndim == 1:
        self.shape = (1, newshape[0])
    return

, ndarray. , .

, -. , ndims 2, .

, , , , numpy codebase, .

  • np.trace ndarray.trace - .
    • np.trace "core/fromnumeric.py"
    • ndarray.trace "core/src/multiarray/methods.c calculate.c"
  • np.trace ndarray
  • ndarray.trace .
    • , tbh

( ). , .

-, . - , .

_array_finalize__ :

def __array_finalize__(self, obj):
    self._getitem = False
    if (isinstance(obj, matrix) and obj._getitem): return
    ndim = self.ndim
    if (ndim == 2):
        return
    if (ndim > 2):
        newshape = tuple([x for x in self.shape if x > 1])
        ndim = len(newshape)
        if ndim == 2:
            self.shape = newshape
            return
        elif (ndim > 2):
            raise ValueError("shape too large to be a matrix.")
    else:
        newshape = self.shape
    return
    if ndim == 0:

        self.shape = (1, 1)
    elif ndim == 1:

        self.shape = (1, newshape[0])
    return

return if-else. X.trace() .

, , .
.

np.trace , .

np.trace ( docstring):

def trace(a, offset=0, axis1=0, axis2=1, dtype=None, out=None):

    return asarray(a).trace(offset, axis1, axis2, dtype, out)

docstring asarray

a. ,          ndarray. a ndarray,         class ndarray .

+2

All Articles