diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2013-08-18 18:40:28 -0600 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2013-09-23 15:11:12 -0600 |
commit | 3beebbc0164afbbcc2b6840cf56174c6c073bb40 (patch) | |
tree | 5eece25d48cd246d78a94e3fcda8c565b6d78258 /numpy/oldnumeric/ma.py | |
parent | 2a1705f4932f446c67074e46bd5fa9098920122d (diff) | |
download | numpy-3beebbc0164afbbcc2b6840cf56174c6c073bb40.tar.gz |
DEP: Remove deprecated modules numarray and oldnumeric.
They were deprecated in 1.8 and scheduled for removal in 1.9.
Closes #3637.
Diffstat (limited to 'numpy/oldnumeric/ma.py')
-rw-r--r-- | numpy/oldnumeric/ma.py | 2296 |
1 files changed, 0 insertions, 2296 deletions
diff --git a/numpy/oldnumeric/ma.py b/numpy/oldnumeric/ma.py deleted file mode 100644 index d41c68edc..000000000 --- a/numpy/oldnumeric/ma.py +++ /dev/null @@ -1,2296 +0,0 @@ -"""MA: a facility for dealing with missing observations - -MA is generally used as a numpy.array look-alike. -by Paul F. Dubois. - -Copyright 1999, 2000, 2001 Regents of the University of California. -Released for unlimited redistribution. -Adapted for numpy_core 2005 by Travis Oliphant and -(mainly) Paul Dubois. - -""" -from __future__ import division, absolute_import, print_function - -import sys -import types -import warnings -from functools import reduce - -import numpy.core.umath as umath -import numpy.core.fromnumeric as fromnumeric -import numpy.core.numeric as numeric -from numpy.core.numeric import newaxis, ndarray, inf -from numpy.core.fromnumeric import amax, amin -from numpy.core.numerictypes import bool_, typecodes -import numpy.core.numeric as numeric -from numpy.compat import bytes, long - -if sys.version_info[0] >= 3: - _MAXINT = sys.maxsize - _MININT = -sys.maxsize - 1 -else: - _MAXINT = sys.maxint - _MININT = -sys.maxint - 1 - - -# Ufunc domain lookup for __array_wrap__ -ufunc_domain = {} -# Ufunc fills lookup for __array__ -ufunc_fills = {} - -MaskType = bool_ -nomask = MaskType(0) -divide_tolerance = 1.e-35 - -class MAError (Exception): - def __init__ (self, args=None): - "Create an exception" - - # The .args attribute must be a tuple. - if not isinstance(args, tuple): - args = (args,) - self.args = args - def __str__(self): - "Calculate the string representation" - return str(self.args[0]) - __repr__ = __str__ - -class _MaskedPrintOption: - "One instance of this class, masked_print_option, is created." - def __init__ (self, display): - "Create the masked print option object." - self.set_display(display) - self._enabled = 1 - - def display (self): - "Show what prints for masked values." - return self._display - - def set_display (self, s): - "set_display(s) sets what prints for masked values." - self._display = s - - def enabled (self): - "Is the use of the display value enabled?" - return self._enabled - - def enable(self, flag=1): - "Set the enabling flag to flag." - self._enabled = flag - - def __str__ (self): - return str(self._display) - - __repr__ = __str__ - -#if you single index into a masked location you get this object. -masked_print_option = _MaskedPrintOption('--') - -# Use single element arrays or scalars. -default_real_fill_value = 1.e20 -default_complex_fill_value = 1.e20 + 0.0j -default_character_fill_value = '-' -default_integer_fill_value = 999999 -default_object_fill_value = '?' - -def default_fill_value (obj): - "Function to calculate default fill value for an object." - if isinstance(obj, float): - return default_real_fill_value - elif isinstance(obj, int) or isinstance(obj, long): - return default_integer_fill_value - elif isinstance(obj, bytes): - return default_character_fill_value - elif isinstance(obj, complex): - return default_complex_fill_value - elif isinstance(obj, MaskedArray) or isinstance(obj, ndarray): - x = obj.dtype.char - if x in typecodes['Float']: - return default_real_fill_value - if x in typecodes['Integer']: - return default_integer_fill_value - if x in typecodes['Complex']: - return default_complex_fill_value - if x in typecodes['Character']: - return default_character_fill_value - if x in typecodes['UnsignedInteger']: - return umath.absolute(default_integer_fill_value) - return default_object_fill_value - else: - return default_object_fill_value - -def minimum_fill_value (obj): - "Function to calculate default fill value suitable for taking minima." - if isinstance(obj, float): - return numeric.inf - elif isinstance(obj, int) or isinstance(obj, long): - return _MAXINT - elif isinstance(obj, MaskedArray) or isinstance(obj, ndarray): - x = obj.dtype.char - if x in typecodes['Float']: - return numeric.inf - if x in typecodes['Integer']: - return _MAXINT - if x in typecodes['UnsignedInteger']: - return _MAXINT - else: - raise TypeError('Unsuitable type for calculating minimum.') - -def maximum_fill_value (obj): - "Function to calculate default fill value suitable for taking maxima." - if isinstance(obj, float): - return -inf - elif isinstance(obj, int) or isinstance(obj, long): - return -_MAXINT - elif isinstance(obj, MaskedArray) or isinstance(obj, ndarray): - x = obj.dtype.char - if x in typecodes['Float']: - return -inf - if x in typecodes['Integer']: - return -_MAXINT - if x in typecodes['UnsignedInteger']: - return 0 - else: - raise TypeError('Unsuitable type for calculating maximum.') - -def set_fill_value (a, fill_value): - "Set fill value of a if it is a masked array." - if isMaskedArray(a): - a.set_fill_value (fill_value) - -def getmask (a): - """Mask of values in a; could be nomask. - Returns nomask if a is not a masked array. - To get an array for sure use getmaskarray.""" - if isinstance(a, MaskedArray): - return a.raw_mask() - else: - return nomask - -def getmaskarray (a): - """Mask of values in a; an array of zeros if mask is nomask - or not a masked array, and is a byte-sized integer. - Do not try to add up entries, for example. - """ - m = getmask(a) - if m is nomask: - return make_mask_none(shape(a)) - else: - return m - -def is_mask (m): - """Is m a legal mask? Does not check contents, only type. - """ - try: - return m.dtype.type is MaskType - except AttributeError: - return False - -def make_mask (m, copy=0, flag=0): - """make_mask(m, copy=0, flag=0) - return m as a mask, creating a copy if necessary or requested. - Can accept any sequence of integers or nomask. Does not check - that contents must be 0s and 1s. - if flag, return nomask if m contains no true elements. - """ - if m is nomask: - return nomask - elif isinstance(m, ndarray): - if m.dtype.type is MaskType: - if copy: - result = numeric.array(m, dtype=MaskType, copy=copy) - else: - result = m - else: - result = m.astype(MaskType) - else: - result = filled(m, True).astype(MaskType) - - if flag and not fromnumeric.sometrue(fromnumeric.ravel(result)): - return nomask - else: - return result - -def make_mask_none (s): - "Return a mask of all zeros of shape s." - result = numeric.zeros(s, dtype=MaskType) - result.shape = s - return result - -def mask_or (m1, m2): - """Logical or of the mask candidates m1 and m2, treating nomask as false. - Result may equal m1 or m2 if the other is nomask. - """ - if m1 is nomask: return make_mask(m2) - if m2 is nomask: return make_mask(m1) - if m1 is m2 and is_mask(m1): return m1 - return make_mask(umath.logical_or(m1, m2)) - -def filled (a, value = None): - """a as a contiguous numeric array with any masked areas replaced by value - if value is None or the special element "masked", get_fill_value(a) - is used instead. - - If a is already a contiguous numeric array, a itself is returned. - - filled(a) can be used to be sure that the result is numeric when - passing an object a to other software ignorant of MA, in particular to - numeric itself. - """ - if isinstance(a, MaskedArray): - return a.filled(value) - elif isinstance(a, ndarray) and a.flags['CONTIGUOUS']: - return a - elif isinstance(a, dict): - return numeric.array(a, 'O') - else: - return numeric.array(a) - -def get_fill_value (a): - """ - The fill value of a, if it has one; otherwise, the default fill value - for that type. - """ - if isMaskedArray(a): - result = a.fill_value() - else: - result = default_fill_value(a) - return result - -def common_fill_value (a, b): - "The common fill_value of a and b, if there is one, or None" - t1 = get_fill_value(a) - t2 = get_fill_value(b) - if t1 == t2: return t1 - return None - -# Domain functions return 1 where the argument(s) are not in the domain. -class domain_check_interval: - "domain_check_interval(a,b)(x) = true where x < a or y > b" - def __init__(self, y1, y2): - "domain_check_interval(a,b)(x) = true where x < a or y > b" - self.y1 = y1 - self.y2 = y2 - - def __call__ (self, x): - "Execute the call behavior." - return umath.logical_or(umath.greater (x, self.y2), - umath.less(x, self.y1) - ) - -class domain_tan: - "domain_tan(eps) = true where abs(cos(x)) < eps)" - def __init__(self, eps): - "domain_tan(eps) = true where abs(cos(x)) < eps)" - self.eps = eps - - def __call__ (self, x): - "Execute the call behavior." - return umath.less(umath.absolute(umath.cos(x)), self.eps) - -class domain_greater: - "domain_greater(v)(x) = true where x <= v" - def __init__(self, critical_value): - "domain_greater(v)(x) = true where x <= v" - self.critical_value = critical_value - - def __call__ (self, x): - "Execute the call behavior." - return umath.less_equal (x, self.critical_value) - -class domain_greater_equal: - "domain_greater_equal(v)(x) = true where x < v" - def __init__(self, critical_value): - "domain_greater_equal(v)(x) = true where x < v" - self.critical_value = critical_value - - def __call__ (self, x): - "Execute the call behavior." - return umath.less (x, self.critical_value) - -class masked_unary_operation: - def __init__ (self, aufunc, fill=0, domain=None): - """ masked_unary_operation(aufunc, fill=0, domain=None) - aufunc(fill) must be defined - self(x) returns aufunc(x) - with masked values where domain(x) is true or getmask(x) is true. - """ - self.f = aufunc - self.fill = fill - self.domain = domain - self.__doc__ = getattr(aufunc, "__doc__", str(aufunc)) - self.__name__ = getattr(aufunc, "__name__", str(aufunc)) - ufunc_domain[aufunc] = domain - ufunc_fills[aufunc] = fill, - - def __call__ (self, a, *args, **kwargs): - "Execute the call behavior." -# numeric tries to return scalars rather than arrays when given scalars. - m = getmask(a) - d1 = filled(a, self.fill) - if self.domain is not None: - m = mask_or(m, self.domain(d1)) - result = self.f(d1, *args, **kwargs) - return masked_array(result, m) - - def __str__ (self): - return "Masked version of " + str(self.f) - - -class domain_safe_divide: - def __init__ (self, tolerance=divide_tolerance): - self.tolerance = tolerance - def __call__ (self, a, b): - return umath.absolute(a) * self.tolerance >= umath.absolute(b) - -class domained_binary_operation: - """Binary operations that have a domain, like divide. These are complicated - so they are a separate class. They have no reduce, outer or accumulate. - """ - def __init__ (self, abfunc, domain, fillx=0, filly=0): - """abfunc(fillx, filly) must be defined. - abfunc(x, filly) = x for all x to enable reduce. - """ - self.f = abfunc - self.domain = domain - self.fillx = fillx - self.filly = filly - self.__doc__ = getattr(abfunc, "__doc__", str(abfunc)) - self.__name__ = getattr(abfunc, "__name__", str(abfunc)) - ufunc_domain[abfunc] = domain - ufunc_fills[abfunc] = fillx, filly - - def __call__(self, a, b): - "Execute the call behavior." - ma = getmask(a) - mb = getmask(b) - d1 = filled(a, self.fillx) - d2 = filled(b, self.filly) - t = self.domain(d1, d2) - - if fromnumeric.sometrue(t, None): - d2 = where(t, self.filly, d2) - mb = mask_or(mb, t) - m = mask_or(ma, mb) - result = self.f(d1, d2) - return masked_array(result, m) - - def __str__ (self): - return "Masked version of " + str(self.f) - -class masked_binary_operation: - def __init__ (self, abfunc, fillx=0, filly=0): - """abfunc(fillx, filly) must be defined. - abfunc(x, filly) = x for all x to enable reduce. - """ - self.f = abfunc - self.fillx = fillx - self.filly = filly - self.__doc__ = getattr(abfunc, "__doc__", str(abfunc)) - ufunc_domain[abfunc] = None - ufunc_fills[abfunc] = fillx, filly - - def __call__ (self, a, b, *args, **kwargs): - "Execute the call behavior." - m = mask_or(getmask(a), getmask(b)) - d1 = filled(a, self.fillx) - d2 = filled(b, self.filly) - result = self.f(d1, d2, *args, **kwargs) - if isinstance(result, ndarray) \ - and m.ndim != 0 \ - and m.shape != result.shape: - m = mask_or(getmaskarray(a), getmaskarray(b)) - return masked_array(result, m) - - def reduce (self, target, axis=0, dtype=None): - """Reduce target along the given axis with this function.""" - m = getmask(target) - t = filled(target, self.filly) - if t.shape == (): - t = t.reshape(1) - if m is not nomask: - m = make_mask(m, copy=1) - m.shape = (1,) - if m is nomask: - t = self.f.reduce(t, axis) - else: - t = masked_array (t, m) - # XXX: "or t.dtype" below is a workaround for what appears - # XXX: to be a bug in reduce. - t = self.f.reduce(filled(t, self.filly), axis, - dtype=dtype or t.dtype) - m = umath.logical_and.reduce(m, axis) - if isinstance(t, ndarray): - return masked_array(t, m, get_fill_value(target)) - elif m: - return masked - else: - return t - - def outer (self, a, b): - "Return the function applied to the outer product of a and b." - ma = getmask(a) - mb = getmask(b) - if ma is nomask and mb is nomask: - m = nomask - else: - ma = getmaskarray(a) - mb = getmaskarray(b) - m = logical_or.outer(ma, mb) - d = self.f.outer(filled(a, self.fillx), filled(b, self.filly)) - return masked_array(d, m) - - def accumulate (self, target, axis=0): - """Accumulate target along axis after filling with y fill value.""" - t = filled(target, self.filly) - return masked_array (self.f.accumulate (t, axis)) - def __str__ (self): - return "Masked version of " + str(self.f) - -sqrt = masked_unary_operation(umath.sqrt, 0.0, domain_greater_equal(0.0)) -log = masked_unary_operation(umath.log, 1.0, domain_greater(0.0)) -log10 = masked_unary_operation(umath.log10, 1.0, domain_greater(0.0)) -exp = masked_unary_operation(umath.exp) -conjugate = masked_unary_operation(umath.conjugate) -sin = masked_unary_operation(umath.sin) -cos = masked_unary_operation(umath.cos) -tan = masked_unary_operation(umath.tan, 0.0, domain_tan(1.e-35)) -arcsin = masked_unary_operation(umath.arcsin, 0.0, domain_check_interval(-1.0, 1.0)) -arccos = masked_unary_operation(umath.arccos, 0.0, domain_check_interval(-1.0, 1.0)) -arctan = masked_unary_operation(umath.arctan) -# Missing from numeric -arcsinh = masked_unary_operation(umath.arcsinh) -arccosh = masked_unary_operation(umath.arccosh, 1.0, domain_greater_equal(1.0)) -arctanh = masked_unary_operation(umath.arctanh, 0.0, domain_check_interval(-1.0+1e-15, 1.0-1e-15)) -sinh = masked_unary_operation(umath.sinh) -cosh = masked_unary_operation(umath.cosh) -tanh = masked_unary_operation(umath.tanh) -absolute = masked_unary_operation(umath.absolute) -fabs = masked_unary_operation(umath.fabs) -negative = masked_unary_operation(umath.negative) - -def nonzero(a): - """returns the indices of the elements of a which are not zero - and not masked - """ - return numeric.asarray(filled(a, 0).nonzero()) - -around = masked_unary_operation(fromnumeric.round_) -floor = masked_unary_operation(umath.floor) -ceil = masked_unary_operation(umath.ceil) -logical_not = masked_unary_operation(umath.logical_not) - -add = masked_binary_operation(umath.add) -subtract = masked_binary_operation(umath.subtract) -subtract.reduce = None -multiply = masked_binary_operation(umath.multiply, 1, 1) -divide = domained_binary_operation(umath.divide, domain_safe_divide(), 0, 1) -true_divide = domained_binary_operation(umath.true_divide, domain_safe_divide(), 0, 1) -floor_divide = domained_binary_operation(umath.floor_divide, domain_safe_divide(), 0, 1) -remainder = domained_binary_operation(umath.remainder, domain_safe_divide(), 0, 1) -fmod = domained_binary_operation(umath.fmod, domain_safe_divide(), 0, 1) -hypot = masked_binary_operation(umath.hypot) -arctan2 = masked_binary_operation(umath.arctan2, 0.0, 1.0) -arctan2.reduce = None -equal = masked_binary_operation(umath.equal) -equal.reduce = None -not_equal = masked_binary_operation(umath.not_equal) -not_equal.reduce = None -less_equal = masked_binary_operation(umath.less_equal) -less_equal.reduce = None -greater_equal = masked_binary_operation(umath.greater_equal) -greater_equal.reduce = None -less = masked_binary_operation(umath.less) -less.reduce = None -greater = masked_binary_operation(umath.greater) -greater.reduce = None -logical_and = masked_binary_operation(umath.logical_and) -alltrue = masked_binary_operation(umath.logical_and, 1, 1).reduce -logical_or = masked_binary_operation(umath.logical_or) -sometrue = logical_or.reduce -logical_xor = masked_binary_operation(umath.logical_xor) -bitwise_and = masked_binary_operation(umath.bitwise_and) -bitwise_or = masked_binary_operation(umath.bitwise_or) -bitwise_xor = masked_binary_operation(umath.bitwise_xor) - -def rank (object): - return fromnumeric.rank(filled(object)) - -def shape (object): - return fromnumeric.shape(filled(object)) - -def size (object, axis=None): - return fromnumeric.size(filled(object), axis) - -class MaskedArray (object): - """Arrays with possibly masked values. - Masked values of 1 exclude the corresponding element from - any computation. - - Construction: - x = array(data, dtype=None, copy=True, order=False, - mask = nomask, fill_value=None) - - If copy=False, every effort is made not to copy the data: - If data is a MaskedArray, and argument mask=nomask, - then the candidate data is data.data and the - mask used is data.mask. If data is a numeric array, - it is used as the candidate raw data. - If dtype is not None and - is != data.dtype.char then a data copy is required. - Otherwise, the candidate is used. - - If a data copy is required, raw data stored is the result of: - numeric.array(data, dtype=dtype.char, copy=copy) - - If mask is nomask there are no masked values. Otherwise mask must - be convertible to an array of booleans with the same shape as x. - - fill_value is used to fill in masked values when necessary, - such as when printing and in method/function filled(). - The fill_value is not used for computation within this module. - """ - __array_priority__ = 10.1 - def __init__(self, data, dtype=None, copy=True, order=False, - mask=nomask, fill_value=None): - """array(data, dtype=None, copy=True, order=False, mask=nomask, fill_value=None) - If data already a numeric array, its dtype becomes the default value of dtype. - """ - if dtype is None: - tc = None - else: - tc = numeric.dtype(dtype) - need_data_copied = copy - if isinstance(data, MaskedArray): - c = data.data - if tc is None: - tc = c.dtype - elif tc != c.dtype: - need_data_copied = True - if mask is nomask: - mask = data.mask - elif mask is not nomask: #attempting to change the mask - need_data_copied = True - - elif isinstance(data, ndarray): - c = data - if tc is None: - tc = c.dtype - elif tc != c.dtype: - need_data_copied = True - else: - need_data_copied = False #because I'll do it now - c = numeric.array(data, dtype=tc, copy=True, order=order) - tc = c.dtype - - if need_data_copied: - if tc == c.dtype: - self._data = numeric.array(c, dtype=tc, copy=True, order=order) - else: - self._data = c.astype(tc) - else: - self._data = c - - if mask is nomask: - self._mask = nomask - self._shared_mask = 0 - else: - self._mask = make_mask (mask) - if self._mask is nomask: - self._shared_mask = 0 - else: - self._shared_mask = (self._mask is mask) - nm = size(self._mask) - nd = size(self._data) - if nm != nd: - if nm == 1: - self._mask = fromnumeric.resize(self._mask, self._data.shape) - self._shared_mask = 0 - elif nd == 1: - self._data = fromnumeric.resize(self._data, self._mask.shape) - self._data.shape = self._mask.shape - else: - raise MAError("Mask and data not compatible.") - elif nm == 1 and shape(self._mask) != shape(self._data): - self.unshare_mask() - self._mask.shape = self._data.shape - - self.set_fill_value(fill_value) - - def __array__ (self, t=None, context=None): - "Special hook for numeric. Converts to numeric if possible." - if self._mask is not nomask: - if fromnumeric.ravel(self._mask).any(): - if context is None: - warnings.warn("Cannot automatically convert masked array to "\ - "numeric because data\n is masked in one or "\ - "more locations."); - return self._data - #raise MAError( - # """Cannot automatically convert masked array to numeric because data - # is masked in one or more locations. - # """) - else: - func, args, i = context - fills = ufunc_fills.get(func) - if fills is None: - raise MAError("%s not known to ma" % func) - return self.filled(fills[i]) - else: # Mask is all false - # Optimize to avoid future invocations of this section. - self._mask = nomask - self._shared_mask = 0 - if t: - return self._data.astype(t) - else: - return self._data - - def __array_wrap__ (self, array, context=None): - """Special hook for ufuncs. - - Wraps the numpy array and sets the mask according to - context. - """ - if context is None: - return MaskedArray(array, copy=False, mask=nomask) - func, args = context[:2] - domain = ufunc_domain[func] - m = reduce(mask_or, [getmask(a) for a in args]) - if domain is not None: - m = mask_or(m, domain(*[getattr(a, '_data', a) - for a in args])) - if m is not nomask: - try: - shape = array.shape - except AttributeError: - pass - else: - if m.shape != shape: - m = reduce(mask_or, [getmaskarray(a) for a in args]) - - return MaskedArray(array, copy=False, mask=m) - - def _get_shape(self): - "Return the current shape." - return self._data.shape - - def _set_shape (self, newshape): - "Set the array's shape." - self._data.shape = newshape - if self._mask is not nomask: - self._mask = self._mask.copy() - self._mask.shape = newshape - - def _get_flat(self): - """Calculate the flat value. - """ - if self._mask is nomask: - return masked_array(self._data.ravel(), mask=nomask, - fill_value = self.fill_value()) - else: - return masked_array(self._data.ravel(), - mask=self._mask.ravel(), - fill_value = self.fill_value()) - - def _set_flat (self, value): - "x.flat = value" - y = self.ravel() - y[:] = value - - def _get_real(self): - "Get the real part of a complex array." - if self._mask is nomask: - return masked_array(self._data.real, mask=nomask, - fill_value = self.fill_value()) - else: - return masked_array(self._data.real, mask=self._mask, - fill_value = self.fill_value()) - - def _set_real (self, value): - "x.real = value" - y = self.real - y[...] = value - - def _get_imaginary(self): - "Get the imaginary part of a complex array." - if self._mask is nomask: - return masked_array(self._data.imag, mask=nomask, - fill_value = self.fill_value()) - else: - return masked_array(self._data.imag, mask=self._mask, - fill_value = self.fill_value()) - - def _set_imaginary (self, value): - "x.imaginary = value" - y = self.imaginary - y[...] = value - - def __str__(self): - """Calculate the str representation, using masked for fill if - it is enabled. Otherwise fill with fill value. - """ - if masked_print_option.enabled(): - f = masked_print_option - # XXX: Without the following special case masked - # XXX: would print as "[--]", not "--". Can we avoid - # XXX: checks for masked by choosing a different value - # XXX: for the masked singleton? 2005-01-05 -- sasha - if self is masked: - return str(f) - m = self._mask - if m is not nomask and m.shape == () and m: - return str(f) - # convert to object array to make filled work - self = self.astype(object) - else: - f = self.fill_value() - res = self.filled(f) - return str(res) - - def __repr__(self): - """Calculate the repr representation, using masked for fill if - it is enabled. Otherwise fill with fill value. - """ - with_mask = """\ -array(data = - %(data)s, - mask = - %(mask)s, - fill_value=%(fill)s) -""" - with_mask1 = """\ -array(data = %(data)s, - mask = %(mask)s, - fill_value=%(fill)s) -""" - without_mask = """array( - %(data)s)""" - without_mask1 = """array(%(data)s)""" - - n = len(self.shape) - if self._mask is nomask: - if n <= 1: - return without_mask1 % {'data':str(self.filled())} - return without_mask % {'data':str(self.filled())} - else: - if n <= 1: - return with_mask % { - 'data': str(self.filled()), - 'mask': str(self._mask), - 'fill': str(self.fill_value()) - } - return with_mask % { - 'data': str(self.filled()), - 'mask': str(self._mask), - 'fill': str(self.fill_value()) - } - without_mask1 = """array(%(data)s)""" - if self._mask is nomask: - return without_mask % {'data':str(self.filled())} - else: - return with_mask % { - 'data': str(self.filled()), - 'mask': str(self._mask), - 'fill': str(self.fill_value()) - } - - def __float__(self): - "Convert self to float." - self.unmask() - if self._mask is not nomask: - raise MAError('Cannot convert masked element to a Python float.') - return float(self.data.item()) - - def __int__(self): - "Convert self to int." - self.unmask() - if self._mask is not nomask: - raise MAError('Cannot convert masked element to a Python int.') - return int(self.data.item()) - - def __getitem__(self, i): - "Get item described by i. Not a copy as in previous versions." - self.unshare_mask() - m = self._mask - dout = self._data[i] - if m is nomask: - try: - if dout.size == 1: - return dout - else: - return masked_array(dout, fill_value=self._fill_value) - except AttributeError: - return dout - mi = m[i] - if mi.size == 1: - if mi: - return masked - else: - return dout - else: - return masked_array(dout, mi, fill_value=self._fill_value) - -# -------- -# setitem and setslice notes -# note that if value is masked, it means to mask those locations. -# setting a value changes the mask to match the value in those locations. - - def __setitem__(self, index, value): - "Set item described by index. If value is masked, mask those locations." - d = self._data - if self is masked: - raise MAError('Cannot alter masked elements.') - if value is masked: - if self._mask is nomask: - self._mask = make_mask_none(d.shape) - self._shared_mask = False - else: - self.unshare_mask() - self._mask[index] = True - return - m = getmask(value) - value = filled(value).astype(d.dtype) - d[index] = value - if m is nomask: - if self._mask is not nomask: - self.unshare_mask() - self._mask[index] = False - else: - if self._mask is nomask: - self._mask = make_mask_none(d.shape) - self._shared_mask = True - else: - self.unshare_mask() - self._mask[index] = m - - def __nonzero__(self): - """returns true if any element is non-zero or masked - - """ - # XXX: This changes bool conversion logic from MA. - # XXX: In MA bool(a) == len(a) != 0, but in numpy - # XXX: scalars do not have len - m = self._mask - d = self._data - return bool(m is not nomask and m.any() - or d is not nomask and d.any()) - - def __bool__(self): - """returns true if any element is non-zero or masked - - """ - # XXX: This changes bool conversion logic from MA. - # XXX: In MA bool(a) == len(a) != 0, but in numpy - # XXX: scalars do not have len - m = self._mask - d = self._data - return bool(m is not nomask and m.any() - or d is not nomask and d.any()) - - def __len__ (self): - """Return length of first dimension. This is weird but Python's - slicing behavior depends on it.""" - return len(self._data) - - def __and__(self, other): - "Return bitwise_and" - return bitwise_and(self, other) - - def __or__(self, other): - "Return bitwise_or" - return bitwise_or(self, other) - - def __xor__(self, other): - "Return bitwise_xor" - return bitwise_xor(self, other) - - __rand__ = __and__ - __ror__ = __or__ - __rxor__ = __xor__ - - def __abs__(self): - "Return absolute(self)" - return absolute(self) - - def __neg__(self): - "Return negative(self)" - return negative(self) - - def __pos__(self): - "Return array(self)" - return array(self) - - def __add__(self, other): - "Return add(self, other)" - return add(self, other) - - __radd__ = __add__ - - def __mod__ (self, other): - "Return remainder(self, other)" - return remainder(self, other) - - def __rmod__ (self, other): - "Return remainder(other, self)" - return remainder(other, self) - - def __lshift__ (self, n): - return left_shift(self, n) - - def __rshift__ (self, n): - return right_shift(self, n) - - def __sub__(self, other): - "Return subtract(self, other)" - return subtract(self, other) - - def __rsub__(self, other): - "Return subtract(other, self)" - return subtract(other, self) - - def __mul__(self, other): - "Return multiply(self, other)" - return multiply(self, other) - - __rmul__ = __mul__ - - def __div__(self, other): - "Return divide(self, other)" - return divide(self, other) - - def __rdiv__(self, other): - "Return divide(other, self)" - return divide(other, self) - - def __truediv__(self, other): - "Return divide(self, other)" - return true_divide(self, other) - - def __rtruediv__(self, other): - "Return divide(other, self)" - return true_divide(other, self) - - def __floordiv__(self, other): - "Return divide(self, other)" - return floor_divide(self, other) - - def __rfloordiv__(self, other): - "Return divide(other, self)" - return floor_divide(other, self) - - def __pow__(self, other, third=None): - "Return power(self, other, third)" - return power(self, other, third) - - def __sqrt__(self): - "Return sqrt(self)" - return sqrt(self) - - def __iadd__(self, other): - "Add other to self in place." - t = self._data.dtype.char - f = filled(other, 0) - t1 = f.dtype.char - if t == t1: - pass - elif t in typecodes['Integer']: - if t1 in typecodes['Integer']: - f = f.astype(t) - else: - raise TypeError('Incorrect type for in-place operation.') - elif t in typecodes['Float']: - if t1 in typecodes['Integer']: - f = f.astype(t) - elif t1 in typecodes['Float']: - f = f.astype(t) - else: - raise TypeError('Incorrect type for in-place operation.') - elif t in typecodes['Complex']: - if t1 in typecodes['Integer']: - f = f.astype(t) - elif t1 in typecodes['Float']: - f = f.astype(t) - elif t1 in typecodes['Complex']: - f = f.astype(t) - else: - raise TypeError('Incorrect type for in-place operation.') - else: - raise TypeError('Incorrect type for in-place operation.') - - if self._mask is nomask: - self._data += f - m = getmask(other) - self._mask = m - self._shared_mask = m is not nomask - else: - result = add(self, masked_array(f, mask=getmask(other))) - self._data = result.data - self._mask = result.mask - self._shared_mask = 1 - return self - - def __imul__(self, other): - "Add other to self in place." - t = self._data.dtype.char - f = filled(other, 0) - t1 = f.dtype.char - if t == t1: - pass - elif t in typecodes['Integer']: - if t1 in typecodes['Integer']: - f = f.astype(t) - else: - raise TypeError('Incorrect type for in-place operation.') - elif t in typecodes['Float']: - if t1 in typecodes['Integer']: - f = f.astype(t) - elif t1 in typecodes['Float']: - f = f.astype(t) - else: - raise TypeError('Incorrect type for in-place operation.') - elif t in typecodes['Complex']: - if t1 in typecodes['Integer']: - f = f.astype(t) - elif t1 in typecodes['Float']: - f = f.astype(t) - elif t1 in typecodes['Complex']: - f = f.astype(t) - else: - raise TypeError('Incorrect type for in-place operation.') - else: - raise TypeError('Incorrect type for in-place operation.') - - if self._mask is nomask: - self._data *= f - m = getmask(other) - self._mask = m - self._shared_mask = m is not nomask - else: - result = multiply(self, masked_array(f, mask=getmask(other))) - self._data = result.data - self._mask = result.mask - self._shared_mask = 1 - return self - - def __isub__(self, other): - "Subtract other from self in place." - t = self._data.dtype.char - f = filled(other, 0) - t1 = f.dtype.char - if t == t1: - pass - elif t in typecodes['Integer']: - if t1 in typecodes['Integer']: - f = f.astype(t) - else: - raise TypeError('Incorrect type for in-place operation.') - elif t in typecodes['Float']: - if t1 in typecodes['Integer']: - f = f.astype(t) - elif t1 in typecodes['Float']: - f = f.astype(t) - else: - raise TypeError('Incorrect type for in-place operation.') - elif t in typecodes['Complex']: - if t1 in typecodes['Integer']: - f = f.astype(t) - elif t1 in typecodes['Float']: - f = f.astype(t) - elif t1 in typecodes['Complex']: - f = f.astype(t) - else: - raise TypeError('Incorrect type for in-place operation.') - else: - raise TypeError('Incorrect type for in-place operation.') - - if self._mask is nomask: - self._data -= f - m = getmask(other) - self._mask = m - self._shared_mask = m is not nomask - else: - result = subtract(self, masked_array(f, mask=getmask(other))) - self._data = result.data - self._mask = result.mask - self._shared_mask = 1 - return self - - - - def __idiv__(self, other): - "Divide self by other in place." - t = self._data.dtype.char - f = filled(other, 0) - t1 = f.dtype.char - if t == t1: - pass - elif t in typecodes['Integer']: - if t1 in typecodes['Integer']: - f = f.astype(t) - else: - raise TypeError('Incorrect type for in-place operation.') - elif t in typecodes['Float']: - if t1 in typecodes['Integer']: - f = f.astype(t) - elif t1 in typecodes['Float']: - f = f.astype(t) - else: - raise TypeError('Incorrect type for in-place operation.') - elif t in typecodes['Complex']: - if t1 in typecodes['Integer']: - f = f.astype(t) - elif t1 in typecodes['Float']: - f = f.astype(t) - elif t1 in typecodes['Complex']: - f = f.astype(t) - else: - raise TypeError('Incorrect type for in-place operation.') - else: - raise TypeError('Incorrect type for in-place operation.') - mo = getmask(other) - result = divide(self, masked_array(f, mask=mo)) - self._data = result.data - dm = result.raw_mask() - if dm is not self._mask: - self._mask = dm - self._shared_mask = 1 - return self - - def __eq__(self, other): - return equal(self, other) - - def __ne__(self, other): - return not_equal(self, other) - - def __lt__(self, other): - return less(self, other) - - def __le__(self, other): - return less_equal(self, other) - - def __gt__(self, other): - return greater(self, other) - - def __ge__(self, other): - return greater_equal(self, other) - - def astype (self, tc): - "return self as array of given type." - d = self._data.astype(tc) - return array(d, mask=self._mask) - - def byte_swapped(self): - """Returns the raw data field, byte_swapped. Included for consistency - with numeric but doesn't make sense in this context. - """ - return self._data.byte_swapped() - - def compressed (self): - "A 1-D array of all the non-masked data." - d = fromnumeric.ravel(self._data) - if self._mask is nomask: - return array(d) - else: - m = 1 - fromnumeric.ravel(self._mask) - c = fromnumeric.compress(m, d) - return array(c, copy=0) - - def count (self, axis = None): - "Count of the non-masked elements in a, or along a certain axis." - m = self._mask - s = self._data.shape - ls = len(s) - if m is nomask: - if ls == 0: - return 1 - if ls == 1: - return s[0] - if axis is None: - return reduce(lambda x, y:x*y, s) - else: - n = s[axis] - t = list(s) - del t[axis] - return ones(t) * n - if axis is None: - w = fromnumeric.ravel(m).astype(int) - n1 = size(w) - if n1 == 1: - n2 = w[0] - else: - n2 = umath.add.reduce(w) - return n1 - n2 - else: - n1 = size(m, axis) - n2 = sum(m.astype(int), axis) - return n1 - n2 - - def dot (self, other): - "s.dot(other) = innerproduct(s, other)" - return innerproduct(self, other) - - def fill_value(self): - "Get the current fill value." - return self._fill_value - - def filled (self, fill_value=None): - """A numeric array with masked values filled. If fill_value is None, - use self.fill_value(). - - If mask is nomask, copy data only if not contiguous. - Result is always a contiguous, numeric array. -# Is contiguous really necessary now? - """ - d = self._data - m = self._mask - if m is nomask: - if d.flags['CONTIGUOUS']: - return d - else: - return d.copy() - else: - if fill_value is None: - value = self._fill_value - else: - value = fill_value - - if self is masked: - result = numeric.array(value) - else: - try: - result = numeric.array(d, dtype=d.dtype, copy=1) - result[m] = value - except (TypeError, AttributeError): - #ok, can't put that value in here - value = numeric.array(value, dtype=object) - d = d.astype(object) - result = fromnumeric.choose(m, (d, value)) - return result - - def ids (self): - """Return the ids of the data and mask areas""" - return (id(self._data), id(self._mask)) - - def iscontiguous (self): - "Is the data contiguous?" - return self._data.flags['CONTIGUOUS'] - - def itemsize(self): - "Item size of each data item." - return self._data.itemsize - - - def outer(self, other): - "s.outer(other) = outerproduct(s, other)" - return outerproduct(self, other) - - def put (self, values): - """Set the non-masked entries of self to filled(values). - No change to mask - """ - iota = numeric.arange(self.size) - d = self._data - if self._mask is nomask: - ind = iota - else: - ind = fromnumeric.compress(1 - self._mask, iota) - d[ind] = filled(values).astype(d.dtype) - - def putmask (self, values): - """Set the masked entries of self to filled(values). - Mask changed to nomask. - """ - d = self._data - if self._mask is not nomask: - d[self._mask] = filled(values).astype(d.dtype) - self._shared_mask = 0 - self._mask = nomask - - def ravel (self): - """Return a 1-D view of self.""" - if self._mask is nomask: - return masked_array(self._data.ravel()) - else: - return masked_array(self._data.ravel(), self._mask.ravel()) - - def raw_data (self): - """ Obsolete; use data property instead. - The raw data; portions may be meaningless. - May be noncontiguous. Expert use only.""" - return self._data - data = property(fget=raw_data, - doc="The data, but values at masked locations are meaningless.") - - def raw_mask (self): - """ Obsolete; use mask property instead. - May be noncontiguous. Expert use only. - """ - return self._mask - mask = property(fget=raw_mask, - doc="The mask, may be nomask. Values where mask true are meaningless.") - - def reshape (self, *s): - """This array reshaped to shape s""" - d = self._data.reshape(*s) - if self._mask is nomask: - return masked_array(d) - else: - m = self._mask.reshape(*s) - return masked_array(d, m) - - def set_fill_value (self, v=None): - "Set the fill value to v. Omit v to restore default." - if v is None: - v = default_fill_value (self.raw_data()) - self._fill_value = v - - def _get_ndim(self): - return self._data.ndim - ndim = property(_get_ndim, doc=numeric.ndarray.ndim.__doc__) - - def _get_size (self): - return self._data.size - size = property(fget=_get_size, doc="Number of elements in the array.") -## CHECK THIS: signature of numeric.array.size? - - def _get_dtype(self): - return self._data.dtype - dtype = property(fget=_get_dtype, doc="type of the array elements.") - - def item(self, *args): - "Return Python scalar if possible" - if self._mask is not nomask: - m = self._mask.item(*args) - try: - if m[0]: - return masked - except IndexError: - return masked - return self._data.item(*args) - - def itemset(self, *args): - "Set Python scalar into array" - item = args[-1] - args = args[:-1] - self[args] = item - - def tolist(self, fill_value=None): - "Convert to list" - return self.filled(fill_value).tolist() - - def tostring(self, fill_value=None): - "Convert to string" - return self.filled(fill_value).tostring() - - def unmask (self): - "Replace the mask by nomask if possible." - if self._mask is nomask: return - m = make_mask(self._mask, flag=1) - if m is nomask: - self._mask = nomask - self._shared_mask = 0 - - def unshare_mask (self): - "If currently sharing mask, make a copy." - if self._shared_mask: - self._mask = make_mask (self._mask, copy=1, flag=0) - self._shared_mask = 0 - - def _get_ctypes(self): - return self._data.ctypes - - def _get_T(self): - if (self.ndim < 2): - return self - return self.transpose() - - shape = property(_get_shape, _set_shape, - doc = 'tuple giving the shape of the array') - - flat = property(_get_flat, _set_flat, - doc = 'Access array in flat form.') - - real = property(_get_real, _set_real, - doc = 'Access the real part of the array') - - imaginary = property(_get_imaginary, _set_imaginary, - doc = 'Access the imaginary part of the array') - - imag = imaginary - - ctypes = property(_get_ctypes, None, doc="ctypes") - - T = property(_get_T, None, doc="get transpose") - -#end class MaskedArray - -array = MaskedArray - -def isMaskedArray (x): - "Is x a masked array, that is, an instance of MaskedArray?" - return isinstance(x, MaskedArray) - -isarray = isMaskedArray -isMA = isMaskedArray #backward compatibility - -def allclose (a, b, fill_value=1, rtol=1.e-5, atol=1.e-8): - """ Returns true if all components of a and b are equal - subject to given tolerances. - If fill_value is 1, masked values considered equal. - If fill_value is 0, masked values considered unequal. - The relative error rtol should be positive and << 1.0 - The absolute error atol comes into play for those elements - of b that are very small or zero; it says how small a must be also. - """ - m = mask_or(getmask(a), getmask(b)) - d1 = filled(a) - d2 = filled(b) - x = filled(array(d1, copy=0, mask=m), fill_value).astype(float) - y = filled(array(d2, copy=0, mask=m), 1).astype(float) - d = umath.less_equal(umath.absolute(x-y), atol + rtol * umath.absolute(y)) - return fromnumeric.alltrue(fromnumeric.ravel(d)) - -def allequal (a, b, fill_value=1): - """ - True if all entries of a and b are equal, using - fill_value as a truth value where either or both are masked. - """ - m = mask_or(getmask(a), getmask(b)) - if m is nomask: - x = filled(a) - y = filled(b) - d = umath.equal(x, y) - return fromnumeric.alltrue(fromnumeric.ravel(d)) - elif fill_value: - x = filled(a) - y = filled(b) - d = umath.equal(x, y) - dm = array(d, mask=m, copy=0) - return fromnumeric.alltrue(fromnumeric.ravel(filled(dm, 1))) - else: - return 0 - -def masked_values (data, value, rtol=1.e-5, atol=1.e-8, copy=1): - """ - masked_values(data, value, rtol=1.e-5, atol=1.e-8) - Create a masked array; mask is nomask if possible. - If copy==0, and otherwise possible, result - may share data values with original array. - Let d = filled(data, value). Returns d - masked where abs(data-value)<= atol + rtol * abs(value) - if d is of a floating point type. Otherwise returns - masked_object(d, value, copy) - """ - abs = umath.absolute - d = filled(data, value) - if issubclass(d.dtype.type, numeric.floating): - m = umath.less_equal(abs(d-value), atol+rtol*abs(value)) - m = make_mask(m, flag=1) - return array(d, mask = m, copy=copy, - fill_value=value) - else: - return masked_object(d, value, copy=copy) - -def masked_object (data, value, copy=1): - "Create array masked where exactly data equal to value" - d = filled(data, value) - dm = make_mask(umath.equal(d, value), flag=1) - return array(d, mask=dm, copy=copy, fill_value=value) - -def arange(start, stop=None, step=1, dtype=None): - """Just like range() except it returns a array whose type can be specified - by the keyword argument dtype. - """ - return array(numeric.arange(start, stop, step, dtype)) - -arrayrange = arange - -def fromstring (s, t): - "Construct a masked array from a string. Result will have no mask." - return masked_array(numeric.fromstring(s, t)) - -def left_shift (a, n): - "Left shift n bits" - m = getmask(a) - if m is nomask: - d = umath.left_shift(filled(a), n) - return masked_array(d) - else: - d = umath.left_shift(filled(a, 0), n) - return masked_array(d, m) - -def right_shift (a, n): - "Right shift n bits" - m = getmask(a) - if m is nomask: - d = umath.right_shift(filled(a), n) - return masked_array(d) - else: - d = umath.right_shift(filled(a, 0), n) - return masked_array(d, m) - -def resize (a, new_shape): - """resize(a, new_shape) returns a new array with the specified shape. - The original array's total size can be any size.""" - m = getmask(a) - if m is not nomask: - m = fromnumeric.resize(m, new_shape) - result = array(fromnumeric.resize(filled(a), new_shape), mask=m) - result.set_fill_value(get_fill_value(a)) - return result - -def new_repeat(a, repeats, axis=None): - """repeat elements of a repeats times along axis - repeats is a sequence of length a.shape[axis] - telling how many times to repeat each element. - """ - af = filled(a) - if isinstance(repeats, int): - if axis is None: - num = af.size - else: - num = af.shape[axis] - repeats = tuple([repeats]*num) - - m = getmask(a) - if m is not nomask: - m = fromnumeric.repeat(m, repeats, axis) - d = fromnumeric.repeat(af, repeats, axis) - result = masked_array(d, m) - result.set_fill_value(get_fill_value(a)) - return result - - - -def identity(n): - """identity(n) returns the identity matrix of shape n x n. - """ - return array(numeric.identity(n)) - -def indices (dimensions, dtype=None): - """indices(dimensions,dtype=None) returns an array representing a grid - of indices with row-only, and column-only variation. - """ - return array(numeric.indices(dimensions, dtype)) - -def zeros (shape, dtype=float): - """zeros(n, dtype=float) = - an array of all zeros of the given length or shape.""" - return array(numeric.zeros(shape, dtype)) - -def ones (shape, dtype=float): - """ones(n, dtype=float) = - an array of all ones of the given length or shape.""" - return array(numeric.ones(shape, dtype)) - -def count (a, axis = None): - "Count of the non-masked elements in a, or along a certain axis." - a = masked_array(a) - return a.count(axis) - -def power (a, b, third=None): - "a**b" - if third is not None: - raise MAError("3-argument power not supported.") - ma = getmask(a) - mb = getmask(b) - m = mask_or(ma, mb) - fa = filled(a, 1) - fb = filled(b, 1) - if fb.dtype.char in typecodes["Integer"]: - return masked_array(umath.power(fa, fb), m) - md = make_mask(umath.less(fa, 0), flag=1) - m = mask_or(m, md) - if m is nomask: - return masked_array(umath.power(fa, fb)) - else: - fa = numeric.where(m, 1, fa) - return masked_array(umath.power(fa, fb), m) - -def masked_array (a, mask=nomask, fill_value=None): - """masked_array(a, mask=nomask) = - array(a, mask=mask, copy=0, fill_value=fill_value) - """ - return array(a, mask=mask, copy=0, fill_value=fill_value) - -def sum (target, axis=None, dtype=None): - if axis is None: - target = ravel(target) - axis = 0 - return add.reduce(target, axis, dtype) - -def product (target, axis=None, dtype=None): - if axis is None: - target = ravel(target) - axis = 0 - return multiply.reduce(target, axis, dtype) - -def new_average (a, axis=None, weights=None, returned = 0): - """average(a, axis=None, weights=None) - Computes average along indicated axis. - If axis is None, average over the entire array - Inputs can be integer or floating types; result is of type float. - - If weights are given, result is sum(a*weights,axis=0)/(sum(weights,axis=0)*1.0) - weights must have a's shape or be the 1-d with length the size - of a in the given axis. - - If returned, return a tuple: the result and the sum of the weights - or count of values. Results will have the same shape. - - masked values in the weights will be set to 0.0 - """ - a = masked_array(a) - mask = a.mask - ash = a.shape - if ash == (): - ash = (1,) - if axis is None: - if mask is nomask: - if weights is None: - n = add.reduce(a.raw_data().ravel()) - d = reduce(lambda x, y: x * y, ash, 1.0) - else: - w = filled(weights, 0.0).ravel() - n = umath.add.reduce(a.raw_data().ravel() * w) - d = umath.add.reduce(w) - del w - else: - if weights is None: - n = add.reduce(a.ravel()) - w = fromnumeric.choose(mask, (1.0, 0.0)).ravel() - d = umath.add.reduce(w) - del w - else: - w = array(filled(weights, 0.0), float, mask=mask).ravel() - n = add.reduce(a.ravel() * w) - d = add.reduce(w) - del w - else: - if mask is nomask: - if weights is None: - d = ash[axis] * 1.0 - n = umath.add.reduce(a.raw_data(), axis) - else: - w = filled(weights, 0.0) - wsh = w.shape - if wsh == (): - wsh = (1,) - if wsh == ash: - w = numeric.array(w, float, copy=0) - n = add.reduce(a*w, axis) - d = add.reduce(w, axis) - del w - elif wsh == (ash[axis],): - r = [newaxis]*len(ash) - r[axis] = slice(None, None, 1) - w = eval ("w["+ repr(tuple(r)) + "] * ones(ash, float)") - n = add.reduce(a*w, axis) - d = add.reduce(w, axis) - del w, r - else: - raise ValueError('average: weights wrong shape.') - else: - if weights is None: - n = add.reduce(a, axis) - w = numeric.choose(mask, (1.0, 0.0)) - d = umath.add.reduce(w, axis) - del w - else: - w = filled(weights, 0.0) - wsh = w.shape - if wsh == (): - wsh = (1,) - if wsh == ash: - w = array(w, float, mask=mask, copy=0) - n = add.reduce(a*w, axis) - d = add.reduce(w, axis) - elif wsh == (ash[axis],): - r = [newaxis]*len(ash) - r[axis] = slice(None, None, 1) - w = eval ("w["+ repr(tuple(r)) + "] * masked_array(ones(ash, float), mask)") - n = add.reduce(a*w, axis) - d = add.reduce(w, axis) - else: - raise ValueError('average: weights wrong shape.') - del w - #print n, d, repr(mask), repr(weights) - if n is masked or d is masked: return masked - result = divide (n, d) - del n - - if isinstance(result, MaskedArray): - result.unmask() - if returned: - if not isinstance(d, MaskedArray): - d = masked_array(d) - if not d.shape == result.shape: - d = ones(result.shape, float) * d - d.unmask() - if returned: - return result, d - else: - return result - -def where (condition, x, y): - """where(condition, x, y) is x where condition is nonzero, y otherwise. - condition must be convertible to an integer array. - Answer is always the shape of condition. - The type depends on x and y. It is integer if both x and y are - the value masked. - """ - fc = filled(not_equal(condition, 0), 0) - xv = filled(x) - xm = getmask(x) - yv = filled(y) - ym = getmask(y) - d = numeric.choose(fc, (yv, xv)) - md = numeric.choose(fc, (ym, xm)) - m = getmask(condition) - m = make_mask(mask_or(m, md), copy=0, flag=1) - return masked_array(d, m) - -def choose (indices, t, out=None, mode='raise'): - "Returns array shaped like indices with elements chosen from t" - def fmask (x): - if x is masked: return 1 - return filled(x) - def nmask (x): - if x is masked: return 1 - m = getmask(x) - if m is nomask: return 0 - return m - c = filled(indices, 0) - masks = [nmask(x) for x in t] - a = [fmask(x) for x in t] - d = numeric.choose(c, a) - m = numeric.choose(c, masks) - m = make_mask(mask_or(m, getmask(indices)), copy=0, flag=1) - return masked_array(d, m) - -def masked_where(condition, x, copy=1): - """Return x as an array masked where condition is true. - Also masked where x or condition masked. - """ - cm = filled(condition, 1) - m = mask_or(getmask(x), cm) - return array(filled(x), copy=copy, mask=m) - -def masked_greater(x, value, copy=1): - "masked_greater(x, value) = x masked where x > value" - return masked_where(greater(x, value), x, copy) - -def masked_greater_equal(x, value, copy=1): - "masked_greater_equal(x, value) = x masked where x >= value" - return masked_where(greater_equal(x, value), x, copy) - -def masked_less(x, value, copy=1): - "masked_less(x, value) = x masked where x < value" - return masked_where(less(x, value), x, copy) - -def masked_less_equal(x, value, copy=1): - "masked_less_equal(x, value) = x masked where x <= value" - return masked_where(less_equal(x, value), x, copy) - -def masked_not_equal(x, value, copy=1): - "masked_not_equal(x, value) = x masked where x != value" - d = filled(x, 0) - c = umath.not_equal(d, value) - m = mask_or(c, getmask(x)) - return array(d, mask=m, copy=copy) - -def masked_equal(x, value, copy=1): - """masked_equal(x, value) = x masked where x == value - For floating point consider masked_values(x, value) instead. - """ - d = filled(x, 0) - c = umath.equal(d, value) - m = mask_or(c, getmask(x)) - return array(d, mask=m, copy=copy) - -def masked_inside(x, v1, v2, copy=1): - """x with mask of all values of x that are inside [v1,v2] - v1 and v2 can be given in either order. - """ - if v2 < v1: - t = v2 - v2 = v1 - v1 = t - d = filled(x, 0) - c = umath.logical_and(umath.less_equal(d, v2), umath.greater_equal(d, v1)) - m = mask_or(c, getmask(x)) - return array(d, mask = m, copy=copy) - -def masked_outside(x, v1, v2, copy=1): - """x with mask of all values of x that are outside [v1,v2] - v1 and v2 can be given in either order. - """ - if v2 < v1: - t = v2 - v2 = v1 - v1 = t - d = filled(x, 0) - c = umath.logical_or(umath.less(d, v1), umath.greater(d, v2)) - m = mask_or(c, getmask(x)) - return array(d, mask = m, copy=copy) - -def reshape (a, *newshape): - "Copy of a with a new shape." - m = getmask(a) - d = filled(a).reshape(*newshape) - if m is nomask: - return masked_array(d) - else: - return masked_array(d, mask=numeric.reshape(m, *newshape)) - -def ravel (a): - "a as one-dimensional, may share data and mask" - m = getmask(a) - d = fromnumeric.ravel(filled(a)) - if m is nomask: - return masked_array(d) - else: - return masked_array(d, mask=numeric.ravel(m)) - -def concatenate (arrays, axis=0): - "Concatenate the arrays along the given axis" - d = [] - for x in arrays: - d.append(filled(x)) - d = numeric.concatenate(d, axis) - for x in arrays: - if getmask(x) is not nomask: break - else: - return masked_array(d) - dm = [] - for x in arrays: - dm.append(getmaskarray(x)) - dm = numeric.concatenate(dm, axis) - return masked_array(d, mask=dm) - -def swapaxes (a, axis1, axis2): - m = getmask(a) - d = masked_array(a).data - if m is nomask: - return masked_array(data=numeric.swapaxes(d, axis1, axis2)) - else: - return masked_array(data=numeric.swapaxes(d, axis1, axis2), - mask=numeric.swapaxes(m, axis1, axis2),) - - -def new_take (a, indices, axis=None, out=None, mode='raise'): - "returns selection of items from a." - m = getmask(a) - # d = masked_array(a).raw_data() - d = masked_array(a).data - if m is nomask: - return masked_array(numeric.take(d, indices, axis)) - else: - return masked_array(numeric.take(d, indices, axis), - mask = numeric.take(m, indices, axis)) - -def transpose(a, axes=None): - "reorder dimensions per tuple axes" - m = getmask(a) - d = filled(a) - if m is nomask: - return masked_array(numeric.transpose(d, axes)) - else: - return masked_array(numeric.transpose(d, axes), - mask = numeric.transpose(m, axes)) - - -def put(a, indices, values, mode='raise'): - """sets storage-indexed locations to corresponding values. - - Values and indices are filled if necessary. - - """ - d = a.raw_data() - ind = filled(indices) - v = filled(values) - numeric.put (d, ind, v) - m = getmask(a) - if m is not nomask: - a.unshare_mask() - numeric.put(a.raw_mask(), ind, 0) - -def putmask(a, mask, values): - "putmask(a, mask, values) sets a where mask is true." - if mask is nomask: - return - numeric.putmask(a.raw_data(), mask, values) - m = getmask(a) - if m is nomask: return - a.unshare_mask() - numeric.putmask(a.raw_mask(), mask, 0) - -def inner(a, b): - """inner(a,b) returns the dot product of two arrays, which has - shape a.shape[:-1] + b.shape[:-1] with elements computed by summing the - product of the elements from the last dimensions of a and b. - Masked elements are replace by zeros. - """ - fa = filled(a, 0) - fb = filled(b, 0) - if len(fa.shape) == 0: fa.shape = (1,) - if len(fb.shape) == 0: fb.shape = (1,) - return masked_array(numeric.inner(fa, fb)) - -innerproduct = inner - -def outer(a, b): - """outer(a,b) = {a[i]*b[j]}, has shape (len(a),len(b))""" - fa = filled(a, 0).ravel() - fb = filled(b, 0).ravel() - d = numeric.outer(fa, fb) - ma = getmask(a) - mb = getmask(b) - if ma is nomask and mb is nomask: - return masked_array(d) - ma = getmaskarray(a) - mb = getmaskarray(b) - m = make_mask(1-numeric.outer(1-ma, 1-mb), copy=0) - return masked_array(d, m) - -outerproduct = outer - -def dot(a, b): - """dot(a,b) returns matrix-multiplication between a and b. The product-sum - is over the last dimension of a and the second-to-last dimension of b. - Masked values are replaced by zeros. See also innerproduct. - """ - return innerproduct(filled(a, 0), numeric.swapaxes(filled(b, 0), -1, -2)) - -def compress(condition, x, dimension=-1, out=None): - """Select those parts of x for which condition is true. - Masked values in condition are considered false. - """ - c = filled(condition, 0) - m = getmask(x) - if m is not nomask: - m = numeric.compress(c, m, dimension) - d = numeric.compress(c, filled(x), dimension) - return masked_array(d, m) - -class _minimum_operation: - "Object to calculate minima" - def __init__ (self): - """minimum(a, b) or minimum(a) - In one argument case returns the scalar minimum. - """ - pass - - def __call__ (self, a, b=None): - "Execute the call behavior." - if b is None: - m = getmask(a) - if m is nomask: - d = amin(filled(a).ravel()) - return d - ac = a.compressed() - if len(ac) == 0: - return masked - else: - return amin(ac.raw_data()) - else: - return where(less(a, b), a, b) - - def reduce (self, target, axis=0): - """Reduce target along the given axis.""" - m = getmask(target) - if m is nomask: - t = filled(target) - return masked_array (umath.minimum.reduce (t, axis)) - else: - t = umath.minimum.reduce(filled(target, minimum_fill_value(target)), axis) - m = umath.logical_and.reduce(m, axis) - return masked_array(t, m, get_fill_value(target)) - - def outer (self, a, b): - "Return the function applied to the outer product of a and b." - ma = getmask(a) - mb = getmask(b) - if ma is nomask and mb is nomask: - m = nomask - else: - ma = getmaskarray(a) - mb = getmaskarray(b) - m = logical_or.outer(ma, mb) - d = umath.minimum.outer(filled(a), filled(b)) - return masked_array(d, m) - -minimum = _minimum_operation () - -class _maximum_operation: - "Object to calculate maxima" - def __init__ (self): - """maximum(a, b) or maximum(a) - In one argument case returns the scalar maximum. - """ - pass - - def __call__ (self, a, b=None): - "Execute the call behavior." - if b is None: - m = getmask(a) - if m is nomask: - d = amax(filled(a).ravel()) - return d - ac = a.compressed() - if len(ac) == 0: - return masked - else: - return amax(ac.raw_data()) - else: - return where(greater(a, b), a, b) - - def reduce (self, target, axis=0): - """Reduce target along the given axis.""" - m = getmask(target) - if m is nomask: - t = filled(target) - return masked_array (umath.maximum.reduce (t, axis)) - else: - t = umath.maximum.reduce(filled(target, maximum_fill_value(target)), axis) - m = umath.logical_and.reduce(m, axis) - return masked_array(t, m, get_fill_value(target)) - - def outer (self, a, b): - "Return the function applied to the outer product of a and b." - ma = getmask(a) - mb = getmask(b) - if ma is nomask and mb is nomask: - m = nomask - else: - ma = getmaskarray(a) - mb = getmaskarray(b) - m = logical_or.outer(ma, mb) - d = umath.maximum.outer(filled(a), filled(b)) - return masked_array(d, m) - -maximum = _maximum_operation () - -def sort (x, axis = -1, fill_value=None): - """If x does not have a mask, return a masked array formed from the - result of numeric.sort(x, axis). - Otherwise, fill x with fill_value. Sort it. - Set a mask where the result is equal to fill_value. - Note that this may have unintended consequences if the data contains the - fill value at a non-masked site. - - If fill_value is not given the default fill value for x's type will be - used. - """ - if fill_value is None: - fill_value = default_fill_value (x) - d = filled(x, fill_value) - s = fromnumeric.sort(d, axis) - if getmask(x) is nomask: - return masked_array(s) - return masked_values(s, fill_value, copy=0) - -def diagonal(a, k = 0, axis1=0, axis2=1): - """diagonal(a,k=0,axis1=0, axis2=1) = the k'th diagonal of a""" - d = fromnumeric.diagonal(filled(a), k, axis1, axis2) - m = getmask(a) - if m is nomask: - return masked_array(d, m) - else: - return masked_array(d, fromnumeric.diagonal(m, k, axis1, axis2)) - -def trace (a, offset=0, axis1=0, axis2=1, dtype=None, out=None): - """trace(a,offset=0, axis1=0, axis2=1) returns the sum along diagonals - (defined by the last two dimenions) of the array. - """ - return diagonal(a, offset, axis1, axis2).sum(dtype=dtype) - -def argsort (x, axis = -1, out=None, fill_value=None): - """Treating masked values as if they have the value fill_value, - return sort indices for sorting along given axis. - if fill_value is None, use get_fill_value(x) - Returns a numpy array. - """ - d = filled(x, fill_value) - return fromnumeric.argsort(d, axis) - -def argmin (x, axis = -1, out=None, fill_value=None): - """Treating masked values as if they have the value fill_value, - return indices for minimum values along given axis. - if fill_value is None, use get_fill_value(x). - Returns a numpy array if x has more than one dimension. - Otherwise, returns a scalar index. - """ - d = filled(x, fill_value) - return fromnumeric.argmin(d, axis) - -def argmax (x, axis = -1, out=None, fill_value=None): - """Treating masked values as if they have the value fill_value, - return sort indices for maximum along given axis. - if fill_value is None, use -get_fill_value(x) if it exists. - Returns a numpy array if x has more than one dimension. - Otherwise, returns a scalar index. - """ - if fill_value is None: - fill_value = default_fill_value (x) - try: - fill_value = - fill_value - except: - pass - d = filled(x, fill_value) - return fromnumeric.argmax(d, axis) - -def fromfunction (f, s): - """apply f to s to create array as in umath.""" - return masked_array(numeric.fromfunction(f, s)) - -def asarray(data, dtype=None): - """asarray(data, dtype) = array(data, dtype, copy=0) - """ - if isinstance(data, MaskedArray) and \ - (dtype is None or dtype == data.dtype): - return data - return array(data, dtype=dtype, copy=0) - -# Add methods to support ndarray interface -# XXX: I is better to to change the masked_*_operation adaptors -# XXX: to wrap ndarray methods directly to create ma.array methods. - -def _m(f): - return types.MethodType(f, None, array) - -def not_implemented(*args, **kwds): - raise NotImplementedError("not yet implemented for numpy.ma arrays") - -array.all = _m(alltrue) -array.any = _m(sometrue) -array.argmax = _m(argmax) -array.argmin = _m(argmin) -array.argsort = _m(argsort) -array.base = property(_m(not_implemented)) -array.byteswap = _m(not_implemented) - -def _choose(self, *args, **kwds): - return choose(self, args) -array.choose = _m(_choose) -del _choose - -def _clip(self,a_min,a_max,out=None): - return MaskedArray(data = self.data.clip(asarray(a_min).data, - asarray(a_max).data), - mask = mask_or(self.mask, - mask_or(getmask(a_min), getmask(a_max)))) -array.clip = _m(_clip) - -def _compress(self, cond, axis=None, out=None): - return compress(cond, self, axis) -array.compress = _m(_compress) -del _compress - -array.conj = array.conjugate = _m(conjugate) -array.copy = _m(not_implemented) - -def _cumprod(self, axis=None, dtype=None, out=None): - m = self.mask - if m is not nomask: - m = umath.logical_or.accumulate(self.mask, axis) - return MaskedArray(data = self.filled(1).cumprod(axis, dtype), mask=m) -array.cumprod = _m(_cumprod) - -def _cumsum(self, axis=None, dtype=None, out=None): - m = self.mask - if m is not nomask: - m = umath.logical_or.accumulate(self.mask, axis) - return MaskedArray(data=self.filled(0).cumsum(axis, dtype), mask=m) -array.cumsum = _m(_cumsum) - -array.diagonal = _m(diagonal) -array.dump = _m(not_implemented) -array.dumps = _m(not_implemented) -array.fill = _m(not_implemented) -array.flags = property(_m(not_implemented)) -array.flatten = _m(ravel) -array.getfield = _m(not_implemented) - -def _max(a, axis=None, out=None): - if out is not None: - raise TypeError("Output arrays Unsupported for masked arrays") - if axis is None: - return maximum(a) - else: - return maximum.reduce(a, axis) -array.max = _m(_max) -del _max -def _min(a, axis=None, out=None): - if out is not None: - raise TypeError("Output arrays Unsupported for masked arrays") - if axis is None: - return minimum(a) - else: - return minimum.reduce(a, axis) -array.min = _m(_min) -del _min -array.mean = _m(new_average) -array.nbytes = property(_m(not_implemented)) -array.newbyteorder = _m(not_implemented) -array.nonzero = _m(nonzero) -array.prod = _m(product) - -def _ptp(a,axis=None,out=None): - return a.max(axis, out)-a.min(axis) -array.ptp = _m(_ptp) -array.repeat = _m(new_repeat) -array.resize = _m(resize) -array.searchsorted = _m(not_implemented) -array.setfield = _m(not_implemented) -array.setflags = _m(not_implemented) -array.sort = _m(not_implemented) # NB: ndarray.sort is inplace - -def _squeeze(self): - try: - result = MaskedArray(data = self.data.squeeze(), - mask = self.mask.squeeze()) - except AttributeError: - result = _wrapit(self, 'squeeze') - return result -array.squeeze = _m(_squeeze) - -array.strides = property(_m(not_implemented)) -array.sum = _m(sum) -def _swapaxes(self, axis1, axis2): - return MaskedArray(data = self.data.swapaxes(axis1, axis2), - mask = self.mask.swapaxes(axis1, axis2)) -array.swapaxes = _m(_swapaxes) -array.take = _m(new_take) -array.tofile = _m(not_implemented) -array.trace = _m(trace) -array.transpose = _m(transpose) - -def _var(self,axis=None,dtype=None, out=None): - if axis is None: - return numeric.asarray(self.compressed()).var() - a = self.swapaxes(axis, 0) - a = a - a.mean(axis=0) - a *= a - a /= a.count(axis=0) - return a.swapaxes(0, axis).sum(axis) -def _std(self,axis=None, dtype=None, out=None): - return (self.var(axis, dtype))**0.5 -array.var = _m(_var) -array.std = _m(_std) - -array.view = _m(not_implemented) -array.round = _m(around) -del _m, not_implemented - - -masked = MaskedArray(0, int, mask=1) - -def repeat(a, repeats, axis=0): - return new_repeat(a, repeats, axis) - -def average(a, axis=0, weights=None, returned=0): - return new_average(a, axis, weights, returned) - -def take(a, indices, axis=0): - return new_take(a, indices, axis) |