python - What does (numpy) __array_wrap__ do? -
i diving scipy linalg module first time, , saw function:
def _makearray(a): new = asarray(a) wrap = getattr(a, "__array_prepare__", new.__array_wrap__) return new, wrap
what __array_wrap__
exactly? found documentation, don't understand explanation:
@ end of every ufunc, method called on input object highest array priority, or output object if 1 specified. ufunc- computed array passed in , whatever returned passed user. subclasses inherit default implementation of method, transforms array new instance of object’s class. subclasses may opt use method transform output array instance of subclass , update metadata before returning array user.
does mean reconverts output of whatever function array
since broken else element-by-element processing? relatedly, regardless of explanation, mean wrap
object? it?
i looking @ code numpy.linalg.inv
...what wrap doing here?
**a, wrap = _makearray(a)** _assertrankatleast2(a) _assertndsquareness(a) t, result_t = _commontype(a) if a.shape[-1] == 0: # inner array 0x0, ufunc cannot handle case **return wrap(empty_like(a, dtype=result_t))** signature = 'd->d' if iscomplextype(t) else 'd->d' extobj = get_linalg_error_extobj(_raise_linalgerror_singular) ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj) return wrap(ainv.astype(result_t))
np.ma.masked_array.__array_wrap__
example of array subclass updates metadata (the mask
).
file: /usr/lib/python3/dist-packages/numpy/ma/core.py definition: np.ma.masked_array.__array_wrap__(self, obj, context=none) source: def __array_wrap__(self, obj, context=none): """ special hook ufuncs. wraps numpy array , sets mask according context. """
np.matrix.__array_wrap__
appears inherit ndarray
version. guess it's because matrix
, while subclass, not have metadata needs updating.
generally idea hook
, it's function called deep within normal processing. default method might not anything. it's way subclass can take special action. class developer writes hooks class user not have worry details. __...__
name isn't part of public interface - though python lets peak under curtain.
an example of wrapping
, i.e returning array same class inputs is:
in [659]: np.cumsum(np.arange(10)) out[659]: array([ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45], dtype=int32) in [660]: np.cumsum(np.matrix(np.arange(10))) out[660]: matrix([[ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45]], dtype=int32 in [665]: np.cumsum(np.ma.masked_array(np.arange(10))) out[665]: masked_array(data = [ 0 1 3 6 10 15 21 28 36 45], mask = false, fill_value = 999999)
the returned values same, array subclass varies, depending on input class.
cumsum
might not best example. masked arrays have own version of cumsum
, 1 treats masked values 0
:
in [679]: m=np.ma.masked_array(np.arange(10),np.arange(10)%2) in [680]: m out[680]: masked_array(data = [0 -- 2 -- 4 -- 6 -- 8 --], mask = [false true false true false true false true false true], fill_value = 999999) in [681]: np.cumsum(m) out[681]: masked_array(data = [0 -- 2 -- 6 -- 12 -- 20 --], mask = [false true false true false true false true false true], fill_value = 999999)
add.accumulate
similar cumsum
, doesn't have special masked version:
in [682]: np.add.accumulate(np.arange(10)) out[682]: array([ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45], dtype=int32) in [683]: np.add.accumulate(m) out[683]: masked_array(data = [ 0 1 3 6 10 15 21 28 36 45], mask = false, fill_value = 999999)
this last masked array, mask default false
, , masked values included in sum.
Comments
Post a Comment