annotate DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/ma/core.py @ 129:89f0fef1fccd

Run repoint if found
author Chris Cannam
date Thu, 07 Feb 2019 11:43:18 +0000
parents 2a2c65a20a8b
children
rev   line source
Chris@87 1 """
Chris@87 2 numpy.ma : a package to handle missing or invalid values.
Chris@87 3
Chris@87 4 This package was initially written for numarray by Paul F. Dubois
Chris@87 5 at Lawrence Livermore National Laboratory.
Chris@87 6 In 2006, the package was completely rewritten by Pierre Gerard-Marchant
Chris@87 7 (University of Georgia) to make the MaskedArray class a subclass of ndarray,
Chris@87 8 and to improve support of structured arrays.
Chris@87 9
Chris@87 10
Chris@87 11 Copyright 1999, 2000, 2001 Regents of the University of California.
Chris@87 12 Released for unlimited redistribution.
Chris@87 13
Chris@87 14 * Adapted for numpy_core 2005 by Travis Oliphant and (mainly) Paul Dubois.
Chris@87 15 * Subclassing of the base `ndarray` 2006 by Pierre Gerard-Marchant
Chris@87 16 (pgmdevlist_AT_gmail_DOT_com)
Chris@87 17 * Improvements suggested by Reggie Dugard (reggie_AT_merfinllc_DOT_com)
Chris@87 18
Chris@87 19 .. moduleauthor:: Pierre Gerard-Marchant
Chris@87 20
Chris@87 21 """
Chris@87 22 # pylint: disable-msg=E1002
Chris@87 23 from __future__ import division, absolute_import, print_function
Chris@87 24
Chris@87 25 import sys
Chris@87 26 import warnings
Chris@87 27 from functools import reduce
Chris@87 28
Chris@87 29 import numpy as np
Chris@87 30 import numpy.core.umath as umath
Chris@87 31 import numpy.core.numerictypes as ntypes
Chris@87 32 from numpy import ndarray, amax, amin, iscomplexobj, bool_
Chris@87 33 from numpy import array as narray
Chris@87 34 from numpy.lib.function_base import angle
Chris@87 35 from numpy.compat import getargspec, formatargspec, long, basestring
Chris@87 36 from numpy import expand_dims as n_expand_dims
Chris@87 37
Chris@87 38 if sys.version_info[0] >= 3:
Chris@87 39 import pickle
Chris@87 40 else:
Chris@87 41 import cPickle as pickle
Chris@87 42
Chris@87 43 __author__ = "Pierre GF Gerard-Marchant"
Chris@87 44 __docformat__ = "restructuredtext en"
Chris@87 45
Chris@87 46 __all__ = ['MAError', 'MaskError', 'MaskType', 'MaskedArray',
Chris@87 47 'bool_',
Chris@87 48 'abs', 'absolute', 'add', 'all', 'allclose', 'allequal', 'alltrue',
Chris@87 49 'amax', 'amin', 'angle', 'anom', 'anomalies', 'any', 'append', 'arange',
Chris@87 50 'arccos', 'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctan2',
Chris@87 51 'arctanh', 'argmax', 'argmin', 'argsort', 'around',
Chris@87 52 'array', 'asarray', 'asanyarray',
Chris@87 53 'bitwise_and', 'bitwise_or', 'bitwise_xor',
Chris@87 54 'ceil', 'choose', 'clip', 'common_fill_value', 'compress',
Chris@87 55 'compressed', 'concatenate', 'conjugate', 'copy', 'cos', 'cosh',
Chris@87 56 'count', 'cumprod', 'cumsum',
Chris@87 57 'default_fill_value', 'diag', 'diagonal', 'diff', 'divide', 'dump',
Chris@87 58 'dumps',
Chris@87 59 'empty', 'empty_like', 'equal', 'exp', 'expand_dims',
Chris@87 60 'fabs', 'flatten_mask', 'fmod', 'filled', 'floor', 'floor_divide',
Chris@87 61 'fix_invalid', 'flatten_structured_array', 'frombuffer', 'fromflex',
Chris@87 62 'fromfunction',
Chris@87 63 'getdata', 'getmask', 'getmaskarray', 'greater', 'greater_equal',
Chris@87 64 'harden_mask', 'hypot',
Chris@87 65 'identity', 'ids', 'indices', 'inner', 'innerproduct',
Chris@87 66 'isMA', 'isMaskedArray', 'is_mask', 'is_masked', 'isarray',
Chris@87 67 'left_shift', 'less', 'less_equal', 'load', 'loads', 'log', 'log2',
Chris@87 68 'log10', 'logical_and', 'logical_not', 'logical_or', 'logical_xor',
Chris@87 69 'make_mask', 'make_mask_descr', 'make_mask_none', 'mask_or',
Chris@87 70 'masked', 'masked_array', 'masked_equal', 'masked_greater',
Chris@87 71 'masked_greater_equal', 'masked_inside', 'masked_invalid',
Chris@87 72 'masked_less', 'masked_less_equal', 'masked_not_equal',
Chris@87 73 'masked_object', 'masked_outside', 'masked_print_option',
Chris@87 74 'masked_singleton', 'masked_values', 'masked_where', 'max', 'maximum',
Chris@87 75 'maximum_fill_value', 'mean', 'min', 'minimum', 'minimum_fill_value',
Chris@87 76 'mod', 'multiply', 'mvoid',
Chris@87 77 'negative', 'nomask', 'nonzero', 'not_equal',
Chris@87 78 'ones', 'outer', 'outerproduct',
Chris@87 79 'power', 'prod', 'product', 'ptp', 'put', 'putmask',
Chris@87 80 'rank', 'ravel', 'remainder', 'repeat', 'reshape', 'resize',
Chris@87 81 'right_shift', 'round_', 'round',
Chris@87 82 'set_fill_value', 'shape', 'sin', 'sinh', 'size', 'sometrue',
Chris@87 83 'sort', 'soften_mask', 'sqrt', 'squeeze', 'std', 'subtract', 'sum',
Chris@87 84 'swapaxes',
Chris@87 85 'take', 'tan', 'tanh', 'trace', 'transpose', 'true_divide',
Chris@87 86 'var', 'where',
Chris@87 87 'zeros']
Chris@87 88
Chris@87 89 MaskType = np.bool_
Chris@87 90 nomask = MaskType(0)
Chris@87 91
Chris@87 92 def doc_note(initialdoc, note):
Chris@87 93 """
Chris@87 94 Adds a Notes section to an existing docstring.
Chris@87 95 """
Chris@87 96 if initialdoc is None:
Chris@87 97 return
Chris@87 98 if note is None:
Chris@87 99 return initialdoc
Chris@87 100 newdoc = """
Chris@87 101 %s
Chris@87 102
Chris@87 103 Notes
Chris@87 104 -----
Chris@87 105 %s
Chris@87 106 """
Chris@87 107 return newdoc % (initialdoc, note)
Chris@87 108
Chris@87 109 def get_object_signature(obj):
Chris@87 110 """
Chris@87 111 Get the signature from obj
Chris@87 112 """
Chris@87 113 try:
Chris@87 114 sig = formatargspec(*getargspec(obj))
Chris@87 115 except TypeError as errmsg:
Chris@87 116 sig = ''
Chris@87 117 # msg = "Unable to retrieve the signature of %s '%s'\n"\
Chris@87 118 # "(Initial error message: %s)"
Chris@87 119 # warnings.warn(msg % (type(obj),
Chris@87 120 # getattr(obj, '__name__', '???'),
Chris@87 121 # errmsg))
Chris@87 122 return sig
Chris@87 123
Chris@87 124
Chris@87 125 #####--------------------------------------------------------------------------
Chris@87 126 #---- --- Exceptions ---
Chris@87 127 #####--------------------------------------------------------------------------
Chris@87 128 class MAError(Exception):
Chris@87 129 """Class for masked array related errors."""
Chris@87 130 pass
Chris@87 131 class MaskError(MAError):
Chris@87 132 "Class for mask related errors."
Chris@87 133 pass
Chris@87 134
Chris@87 135
Chris@87 136 #####--------------------------------------------------------------------------
Chris@87 137 #---- --- Filling options ---
Chris@87 138 #####--------------------------------------------------------------------------
Chris@87 139 # b: boolean - c: complex - f: floats - i: integer - O: object - S: string
Chris@87 140 default_filler = {'b': True,
Chris@87 141 'c' : 1.e20 + 0.0j,
Chris@87 142 'f' : 1.e20,
Chris@87 143 'i' : 999999,
Chris@87 144 'O' : '?',
Chris@87 145 'S' : 'N/A',
Chris@87 146 'u' : 999999,
Chris@87 147 'V' : '???',
Chris@87 148 'U' : 'N/A',
Chris@87 149 'M8[D]' : np.datetime64('NaT', 'D'),
Chris@87 150 'M8[us]' : np.datetime64('NaT', 'us')
Chris@87 151 }
Chris@87 152 max_filler = ntypes._minvals
Chris@87 153 max_filler.update([(k, -np.inf) for k in [np.float32, np.float64]])
Chris@87 154 min_filler = ntypes._maxvals
Chris@87 155 min_filler.update([(k, +np.inf) for k in [np.float32, np.float64]])
Chris@87 156 if 'float128' in ntypes.typeDict:
Chris@87 157 max_filler.update([(np.float128, -np.inf)])
Chris@87 158 min_filler.update([(np.float128, +np.inf)])
Chris@87 159
Chris@87 160
Chris@87 161 def default_fill_value(obj):
Chris@87 162 """
Chris@87 163 Return the default fill value for the argument object.
Chris@87 164
Chris@87 165 The default filling value depends on the datatype of the input
Chris@87 166 array or the type of the input scalar:
Chris@87 167
Chris@87 168 ======== ========
Chris@87 169 datatype default
Chris@87 170 ======== ========
Chris@87 171 bool True
Chris@87 172 int 999999
Chris@87 173 float 1.e20
Chris@87 174 complex 1.e20+0j
Chris@87 175 object '?'
Chris@87 176 string 'N/A'
Chris@87 177 ======== ========
Chris@87 178
Chris@87 179
Chris@87 180 Parameters
Chris@87 181 ----------
Chris@87 182 obj : ndarray, dtype or scalar
Chris@87 183 The array data-type or scalar for which the default fill value
Chris@87 184 is returned.
Chris@87 185
Chris@87 186 Returns
Chris@87 187 -------
Chris@87 188 fill_value : scalar
Chris@87 189 The default fill value.
Chris@87 190
Chris@87 191 Examples
Chris@87 192 --------
Chris@87 193 >>> np.ma.default_fill_value(1)
Chris@87 194 999999
Chris@87 195 >>> np.ma.default_fill_value(np.array([1.1, 2., np.pi]))
Chris@87 196 1e+20
Chris@87 197 >>> np.ma.default_fill_value(np.dtype(complex))
Chris@87 198 (1e+20+0j)
Chris@87 199
Chris@87 200 """
Chris@87 201 if hasattr(obj, 'dtype'):
Chris@87 202 defval = _check_fill_value(None, obj.dtype)
Chris@87 203 elif isinstance(obj, np.dtype):
Chris@87 204 if obj.subdtype:
Chris@87 205 defval = default_filler.get(obj.subdtype[0].kind, '?')
Chris@87 206 elif obj.kind == 'M':
Chris@87 207 defval = default_filler.get(obj.str[1:], '?')
Chris@87 208 else:
Chris@87 209 defval = default_filler.get(obj.kind, '?')
Chris@87 210 elif isinstance(obj, float):
Chris@87 211 defval = default_filler['f']
Chris@87 212 elif isinstance(obj, int) or isinstance(obj, long):
Chris@87 213 defval = default_filler['i']
Chris@87 214 elif isinstance(obj, str):
Chris@87 215 defval = default_filler['S']
Chris@87 216 elif isinstance(obj, unicode):
Chris@87 217 defval = default_filler['U']
Chris@87 218 elif isinstance(obj, complex):
Chris@87 219 defval = default_filler['c']
Chris@87 220 else:
Chris@87 221 defval = default_filler['O']
Chris@87 222 return defval
Chris@87 223
Chris@87 224
Chris@87 225 def _recursive_extremum_fill_value(ndtype, extremum):
Chris@87 226 names = ndtype.names
Chris@87 227 if names:
Chris@87 228 deflist = []
Chris@87 229 for name in names:
Chris@87 230 fval = _recursive_extremum_fill_value(ndtype[name], extremum)
Chris@87 231 deflist.append(fval)
Chris@87 232 return tuple(deflist)
Chris@87 233 return extremum[ndtype]
Chris@87 234
Chris@87 235
Chris@87 236 def minimum_fill_value(obj):
Chris@87 237 """
Chris@87 238 Return the maximum value that can be represented by the dtype of an object.
Chris@87 239
Chris@87 240 This function is useful for calculating a fill value suitable for
Chris@87 241 taking the minimum of an array with a given dtype.
Chris@87 242
Chris@87 243 Parameters
Chris@87 244 ----------
Chris@87 245 obj : ndarray or dtype
Chris@87 246 An object that can be queried for it's numeric type.
Chris@87 247
Chris@87 248 Returns
Chris@87 249 -------
Chris@87 250 val : scalar
Chris@87 251 The maximum representable value.
Chris@87 252
Chris@87 253 Raises
Chris@87 254 ------
Chris@87 255 TypeError
Chris@87 256 If `obj` isn't a suitable numeric type.
Chris@87 257
Chris@87 258 See Also
Chris@87 259 --------
Chris@87 260 maximum_fill_value : The inverse function.
Chris@87 261 set_fill_value : Set the filling value of a masked array.
Chris@87 262 MaskedArray.fill_value : Return current fill value.
Chris@87 263
Chris@87 264 Examples
Chris@87 265 --------
Chris@87 266 >>> import numpy.ma as ma
Chris@87 267 >>> a = np.int8()
Chris@87 268 >>> ma.minimum_fill_value(a)
Chris@87 269 127
Chris@87 270 >>> a = np.int32()
Chris@87 271 >>> ma.minimum_fill_value(a)
Chris@87 272 2147483647
Chris@87 273
Chris@87 274 An array of numeric data can also be passed.
Chris@87 275
Chris@87 276 >>> a = np.array([1, 2, 3], dtype=np.int8)
Chris@87 277 >>> ma.minimum_fill_value(a)
Chris@87 278 127
Chris@87 279 >>> a = np.array([1, 2, 3], dtype=np.float32)
Chris@87 280 >>> ma.minimum_fill_value(a)
Chris@87 281 inf
Chris@87 282
Chris@87 283 """
Chris@87 284 errmsg = "Unsuitable type for calculating minimum."
Chris@87 285 if hasattr(obj, 'dtype'):
Chris@87 286 return _recursive_extremum_fill_value(obj.dtype, min_filler)
Chris@87 287 elif isinstance(obj, float):
Chris@87 288 return min_filler[ntypes.typeDict['float_']]
Chris@87 289 elif isinstance(obj, int):
Chris@87 290 return min_filler[ntypes.typeDict['int_']]
Chris@87 291 elif isinstance(obj, long):
Chris@87 292 return min_filler[ntypes.typeDict['uint']]
Chris@87 293 elif isinstance(obj, np.dtype):
Chris@87 294 return min_filler[obj]
Chris@87 295 else:
Chris@87 296 raise TypeError(errmsg)
Chris@87 297
Chris@87 298
Chris@87 299 def maximum_fill_value(obj):
Chris@87 300 """
Chris@87 301 Return the minimum value that can be represented by the dtype of an object.
Chris@87 302
Chris@87 303 This function is useful for calculating a fill value suitable for
Chris@87 304 taking the maximum of an array with a given dtype.
Chris@87 305
Chris@87 306 Parameters
Chris@87 307 ----------
Chris@87 308 obj : {ndarray, dtype}
Chris@87 309 An object that can be queried for it's numeric type.
Chris@87 310
Chris@87 311 Returns
Chris@87 312 -------
Chris@87 313 val : scalar
Chris@87 314 The minimum representable value.
Chris@87 315
Chris@87 316 Raises
Chris@87 317 ------
Chris@87 318 TypeError
Chris@87 319 If `obj` isn't a suitable numeric type.
Chris@87 320
Chris@87 321 See Also
Chris@87 322 --------
Chris@87 323 minimum_fill_value : The inverse function.
Chris@87 324 set_fill_value : Set the filling value of a masked array.
Chris@87 325 MaskedArray.fill_value : Return current fill value.
Chris@87 326
Chris@87 327 Examples
Chris@87 328 --------
Chris@87 329 >>> import numpy.ma as ma
Chris@87 330 >>> a = np.int8()
Chris@87 331 >>> ma.maximum_fill_value(a)
Chris@87 332 -128
Chris@87 333 >>> a = np.int32()
Chris@87 334 >>> ma.maximum_fill_value(a)
Chris@87 335 -2147483648
Chris@87 336
Chris@87 337 An array of numeric data can also be passed.
Chris@87 338
Chris@87 339 >>> a = np.array([1, 2, 3], dtype=np.int8)
Chris@87 340 >>> ma.maximum_fill_value(a)
Chris@87 341 -128
Chris@87 342 >>> a = np.array([1, 2, 3], dtype=np.float32)
Chris@87 343 >>> ma.maximum_fill_value(a)
Chris@87 344 -inf
Chris@87 345
Chris@87 346 """
Chris@87 347 errmsg = "Unsuitable type for calculating maximum."
Chris@87 348 if hasattr(obj, 'dtype'):
Chris@87 349 return _recursive_extremum_fill_value(obj.dtype, max_filler)
Chris@87 350 elif isinstance(obj, float):
Chris@87 351 return max_filler[ntypes.typeDict['float_']]
Chris@87 352 elif isinstance(obj, int):
Chris@87 353 return max_filler[ntypes.typeDict['int_']]
Chris@87 354 elif isinstance(obj, long):
Chris@87 355 return max_filler[ntypes.typeDict['uint']]
Chris@87 356 elif isinstance(obj, np.dtype):
Chris@87 357 return max_filler[obj]
Chris@87 358 else:
Chris@87 359 raise TypeError(errmsg)
Chris@87 360
Chris@87 361
Chris@87 362 def _recursive_set_default_fill_value(dtypedescr):
Chris@87 363 deflist = []
Chris@87 364 for currentdescr in dtypedescr:
Chris@87 365 currenttype = currentdescr[1]
Chris@87 366 if isinstance(currenttype, list):
Chris@87 367 deflist.append(tuple(_recursive_set_default_fill_value(currenttype)))
Chris@87 368 else:
Chris@87 369 deflist.append(default_fill_value(np.dtype(currenttype)))
Chris@87 370 return tuple(deflist)
Chris@87 371
Chris@87 372 def _recursive_set_fill_value(fillvalue, dtypedescr):
Chris@87 373 fillvalue = np.resize(fillvalue, len(dtypedescr))
Chris@87 374 output_value = []
Chris@87 375 for (fval, descr) in zip(fillvalue, dtypedescr):
Chris@87 376 cdtype = descr[1]
Chris@87 377 if isinstance(cdtype, list):
Chris@87 378 output_value.append(tuple(_recursive_set_fill_value(fval, cdtype)))
Chris@87 379 else:
Chris@87 380 output_value.append(np.array(fval, dtype=cdtype).item())
Chris@87 381 return tuple(output_value)
Chris@87 382
Chris@87 383
Chris@87 384 def _check_fill_value(fill_value, ndtype):
Chris@87 385 """
Chris@87 386 Private function validating the given `fill_value` for the given dtype.
Chris@87 387
Chris@87 388 If fill_value is None, it is set to the default corresponding to the dtype
Chris@87 389 if this latter is standard (no fields). If the datatype is flexible (named
Chris@87 390 fields), fill_value is set to a tuple whose elements are the default fill
Chris@87 391 values corresponding to each field.
Chris@87 392
Chris@87 393 If fill_value is not None, its value is forced to the given dtype.
Chris@87 394
Chris@87 395 """
Chris@87 396 ndtype = np.dtype(ndtype)
Chris@87 397 fields = ndtype.fields
Chris@87 398 if fill_value is None:
Chris@87 399 if fields:
Chris@87 400 descr = ndtype.descr
Chris@87 401 fill_value = np.array(_recursive_set_default_fill_value(descr),
Chris@87 402 dtype=ndtype,)
Chris@87 403 else:
Chris@87 404 fill_value = default_fill_value(ndtype)
Chris@87 405 elif fields:
Chris@87 406 fdtype = [(_[0], _[1]) for _ in ndtype.descr]
Chris@87 407 if isinstance(fill_value, (ndarray, np.void)):
Chris@87 408 try:
Chris@87 409 fill_value = np.array(fill_value, copy=False, dtype=fdtype)
Chris@87 410 except ValueError:
Chris@87 411 err_msg = "Unable to transform %s to dtype %s"
Chris@87 412 raise ValueError(err_msg % (fill_value, fdtype))
Chris@87 413 else:
Chris@87 414 descr = ndtype.descr
Chris@87 415 fill_value = np.asarray(fill_value, dtype=object)
Chris@87 416 fill_value = np.array(_recursive_set_fill_value(fill_value, descr),
Chris@87 417 dtype=ndtype)
Chris@87 418 else:
Chris@87 419 if isinstance(fill_value, basestring) and (ndtype.char not in 'OSVU'):
Chris@87 420 err_msg = "Cannot set fill value of string with array of dtype %s"
Chris@87 421 raise TypeError(err_msg % ndtype)
Chris@87 422 else:
Chris@87 423 # In case we want to convert 1e20 to int...
Chris@87 424 try:
Chris@87 425 fill_value = np.array(fill_value, copy=False, dtype=ndtype)
Chris@87 426 except OverflowError:
Chris@87 427 # Raise TypeError instead of OverflowError. OverflowError
Chris@87 428 # is seldom used, and the real problem here is that the
Chris@87 429 # passed fill_value is not compatible with the ndtype.
Chris@87 430 err_msg = "Fill value %s overflows dtype %s"
Chris@87 431 raise TypeError(err_msg % (fill_value, ndtype))
Chris@87 432 return np.array(fill_value)
Chris@87 433
Chris@87 434
Chris@87 435 def set_fill_value(a, fill_value):
Chris@87 436 """
Chris@87 437 Set the filling value of a, if a is a masked array.
Chris@87 438
Chris@87 439 This function changes the fill value of the masked array `a` in place.
Chris@87 440 If `a` is not a masked array, the function returns silently, without
Chris@87 441 doing anything.
Chris@87 442
Chris@87 443 Parameters
Chris@87 444 ----------
Chris@87 445 a : array_like
Chris@87 446 Input array.
Chris@87 447 fill_value : dtype
Chris@87 448 Filling value. A consistency test is performed to make sure
Chris@87 449 the value is compatible with the dtype of `a`.
Chris@87 450
Chris@87 451 Returns
Chris@87 452 -------
Chris@87 453 None
Chris@87 454 Nothing returned by this function.
Chris@87 455
Chris@87 456 See Also
Chris@87 457 --------
Chris@87 458 maximum_fill_value : Return the default fill value for a dtype.
Chris@87 459 MaskedArray.fill_value : Return current fill value.
Chris@87 460 MaskedArray.set_fill_value : Equivalent method.
Chris@87 461
Chris@87 462 Examples
Chris@87 463 --------
Chris@87 464 >>> import numpy.ma as ma
Chris@87 465 >>> a = np.arange(5)
Chris@87 466 >>> a
Chris@87 467 array([0, 1, 2, 3, 4])
Chris@87 468 >>> a = ma.masked_where(a < 3, a)
Chris@87 469 >>> a
Chris@87 470 masked_array(data = [-- -- -- 3 4],
Chris@87 471 mask = [ True True True False False],
Chris@87 472 fill_value=999999)
Chris@87 473 >>> ma.set_fill_value(a, -999)
Chris@87 474 >>> a
Chris@87 475 masked_array(data = [-- -- -- 3 4],
Chris@87 476 mask = [ True True True False False],
Chris@87 477 fill_value=-999)
Chris@87 478
Chris@87 479 Nothing happens if `a` is not a masked array.
Chris@87 480
Chris@87 481 >>> a = range(5)
Chris@87 482 >>> a
Chris@87 483 [0, 1, 2, 3, 4]
Chris@87 484 >>> ma.set_fill_value(a, 100)
Chris@87 485 >>> a
Chris@87 486 [0, 1, 2, 3, 4]
Chris@87 487 >>> a = np.arange(5)
Chris@87 488 >>> a
Chris@87 489 array([0, 1, 2, 3, 4])
Chris@87 490 >>> ma.set_fill_value(a, 100)
Chris@87 491 >>> a
Chris@87 492 array([0, 1, 2, 3, 4])
Chris@87 493
Chris@87 494 """
Chris@87 495 if isinstance(a, MaskedArray):
Chris@87 496 a.set_fill_value(fill_value)
Chris@87 497 return
Chris@87 498
Chris@87 499 def get_fill_value(a):
Chris@87 500 """
Chris@87 501 Return the filling value of a, if any. Otherwise, returns the
Chris@87 502 default filling value for that type.
Chris@87 503
Chris@87 504 """
Chris@87 505 if isinstance(a, MaskedArray):
Chris@87 506 result = a.fill_value
Chris@87 507 else:
Chris@87 508 result = default_fill_value(a)
Chris@87 509 return result
Chris@87 510
Chris@87 511 def common_fill_value(a, b):
Chris@87 512 """
Chris@87 513 Return the common filling value of two masked arrays, if any.
Chris@87 514
Chris@87 515 If ``a.fill_value == b.fill_value``, return the fill value,
Chris@87 516 otherwise return None.
Chris@87 517
Chris@87 518 Parameters
Chris@87 519 ----------
Chris@87 520 a, b : MaskedArray
Chris@87 521 The masked arrays for which to compare fill values.
Chris@87 522
Chris@87 523 Returns
Chris@87 524 -------
Chris@87 525 fill_value : scalar or None
Chris@87 526 The common fill value, or None.
Chris@87 527
Chris@87 528 Examples
Chris@87 529 --------
Chris@87 530 >>> x = np.ma.array([0, 1.], fill_value=3)
Chris@87 531 >>> y = np.ma.array([0, 1.], fill_value=3)
Chris@87 532 >>> np.ma.common_fill_value(x, y)
Chris@87 533 3.0
Chris@87 534
Chris@87 535 """
Chris@87 536 t1 = get_fill_value(a)
Chris@87 537 t2 = get_fill_value(b)
Chris@87 538 if t1 == t2:
Chris@87 539 return t1
Chris@87 540 return None
Chris@87 541
Chris@87 542
Chris@87 543 #####--------------------------------------------------------------------------
Chris@87 544 def filled(a, fill_value=None):
Chris@87 545 """
Chris@87 546 Return input as an array with masked data replaced by a fill value.
Chris@87 547
Chris@87 548 If `a` is not a `MaskedArray`, `a` itself is returned.
Chris@87 549 If `a` is a `MaskedArray` and `fill_value` is None, `fill_value` is set to
Chris@87 550 ``a.fill_value``.
Chris@87 551
Chris@87 552 Parameters
Chris@87 553 ----------
Chris@87 554 a : MaskedArray or array_like
Chris@87 555 An input object.
Chris@87 556 fill_value : scalar, optional
Chris@87 557 Filling value. Default is None.
Chris@87 558
Chris@87 559 Returns
Chris@87 560 -------
Chris@87 561 a : ndarray
Chris@87 562 The filled array.
Chris@87 563
Chris@87 564 See Also
Chris@87 565 --------
Chris@87 566 compressed
Chris@87 567
Chris@87 568 Examples
Chris@87 569 --------
Chris@87 570 >>> x = np.ma.array(np.arange(9).reshape(3, 3), mask=[[1, 0, 0],
Chris@87 571 ... [1, 0, 0],
Chris@87 572 ... [0, 0, 0]])
Chris@87 573 >>> x.filled()
Chris@87 574 array([[999999, 1, 2],
Chris@87 575 [999999, 4, 5],
Chris@87 576 [ 6, 7, 8]])
Chris@87 577
Chris@87 578 """
Chris@87 579 if hasattr(a, 'filled'):
Chris@87 580 return a.filled(fill_value)
Chris@87 581 elif isinstance(a, ndarray):
Chris@87 582 # Should we check for contiguity ? and a.flags['CONTIGUOUS']:
Chris@87 583 return a
Chris@87 584 elif isinstance(a, dict):
Chris@87 585 return np.array(a, 'O')
Chris@87 586 else:
Chris@87 587 return np.array(a)
Chris@87 588
Chris@87 589 #####--------------------------------------------------------------------------
Chris@87 590 def get_masked_subclass(*arrays):
Chris@87 591 """
Chris@87 592 Return the youngest subclass of MaskedArray from a list of (masked) arrays.
Chris@87 593 In case of siblings, the first listed takes over.
Chris@87 594
Chris@87 595 """
Chris@87 596 if len(arrays) == 1:
Chris@87 597 arr = arrays[0]
Chris@87 598 if isinstance(arr, MaskedArray):
Chris@87 599 rcls = type(arr)
Chris@87 600 else:
Chris@87 601 rcls = MaskedArray
Chris@87 602 else:
Chris@87 603 arrcls = [type(a) for a in arrays]
Chris@87 604 rcls = arrcls[0]
Chris@87 605 if not issubclass(rcls, MaskedArray):
Chris@87 606 rcls = MaskedArray
Chris@87 607 for cls in arrcls[1:]:
Chris@87 608 if issubclass(cls, rcls):
Chris@87 609 rcls = cls
Chris@87 610 # Don't return MaskedConstant as result: revert to MaskedArray
Chris@87 611 if rcls.__name__ == 'MaskedConstant':
Chris@87 612 return MaskedArray
Chris@87 613 return rcls
Chris@87 614
Chris@87 615 #####--------------------------------------------------------------------------
Chris@87 616 def getdata(a, subok=True):
Chris@87 617 """
Chris@87 618 Return the data of a masked array as an ndarray.
Chris@87 619
Chris@87 620 Return the data of `a` (if any) as an ndarray if `a` is a ``MaskedArray``,
Chris@87 621 else return `a` as a ndarray or subclass (depending on `subok`) if not.
Chris@87 622
Chris@87 623 Parameters
Chris@87 624 ----------
Chris@87 625 a : array_like
Chris@87 626 Input ``MaskedArray``, alternatively a ndarray or a subclass thereof.
Chris@87 627 subok : bool
Chris@87 628 Whether to force the output to be a `pure` ndarray (False) or to
Chris@87 629 return a subclass of ndarray if appropriate (True, default).
Chris@87 630
Chris@87 631 See Also
Chris@87 632 --------
Chris@87 633 getmask : Return the mask of a masked array, or nomask.
Chris@87 634 getmaskarray : Return the mask of a masked array, or full array of False.
Chris@87 635
Chris@87 636 Examples
Chris@87 637 --------
Chris@87 638 >>> import numpy.ma as ma
Chris@87 639 >>> a = ma.masked_equal([[1,2],[3,4]], 2)
Chris@87 640 >>> a
Chris@87 641 masked_array(data =
Chris@87 642 [[1 --]
Chris@87 643 [3 4]],
Chris@87 644 mask =
Chris@87 645 [[False True]
Chris@87 646 [False False]],
Chris@87 647 fill_value=999999)
Chris@87 648 >>> ma.getdata(a)
Chris@87 649 array([[1, 2],
Chris@87 650 [3, 4]])
Chris@87 651
Chris@87 652 Equivalently use the ``MaskedArray`` `data` attribute.
Chris@87 653
Chris@87 654 >>> a.data
Chris@87 655 array([[1, 2],
Chris@87 656 [3, 4]])
Chris@87 657
Chris@87 658 """
Chris@87 659 try:
Chris@87 660 data = a._data
Chris@87 661 except AttributeError:
Chris@87 662 data = np.array(a, copy=False, subok=subok)
Chris@87 663 if not subok:
Chris@87 664 return data.view(ndarray)
Chris@87 665 return data
Chris@87 666 get_data = getdata
Chris@87 667
Chris@87 668
Chris@87 669 def fix_invalid(a, mask=nomask, copy=True, fill_value=None):
Chris@87 670 """
Chris@87 671 Return input with invalid data masked and replaced by a fill value.
Chris@87 672
Chris@87 673 Invalid data means values of `nan`, `inf`, etc.
Chris@87 674
Chris@87 675 Parameters
Chris@87 676 ----------
Chris@87 677 a : array_like
Chris@87 678 Input array, a (subclass of) ndarray.
Chris@87 679 copy : bool, optional
Chris@87 680 Whether to use a copy of `a` (True) or to fix `a` in place (False).
Chris@87 681 Default is True.
Chris@87 682 fill_value : scalar, optional
Chris@87 683 Value used for fixing invalid data. Default is None, in which case
Chris@87 684 the ``a.fill_value`` is used.
Chris@87 685
Chris@87 686 Returns
Chris@87 687 -------
Chris@87 688 b : MaskedArray
Chris@87 689 The input array with invalid entries fixed.
Chris@87 690
Chris@87 691 Notes
Chris@87 692 -----
Chris@87 693 A copy is performed by default.
Chris@87 694
Chris@87 695 Examples
Chris@87 696 --------
Chris@87 697 >>> x = np.ma.array([1., -1, np.nan, np.inf], mask=[1] + [0]*3)
Chris@87 698 >>> x
Chris@87 699 masked_array(data = [-- -1.0 nan inf],
Chris@87 700 mask = [ True False False False],
Chris@87 701 fill_value = 1e+20)
Chris@87 702 >>> np.ma.fix_invalid(x)
Chris@87 703 masked_array(data = [-- -1.0 -- --],
Chris@87 704 mask = [ True False True True],
Chris@87 705 fill_value = 1e+20)
Chris@87 706
Chris@87 707 >>> fixed = np.ma.fix_invalid(x)
Chris@87 708 >>> fixed.data
Chris@87 709 array([ 1.00000000e+00, -1.00000000e+00, 1.00000000e+20,
Chris@87 710 1.00000000e+20])
Chris@87 711 >>> x.data
Chris@87 712 array([ 1., -1., NaN, Inf])
Chris@87 713
Chris@87 714 """
Chris@87 715 a = masked_array(a, copy=copy, mask=mask, subok=True)
Chris@87 716 #invalid = (numpy.isnan(a._data) | numpy.isinf(a._data))
Chris@87 717 invalid = np.logical_not(np.isfinite(a._data))
Chris@87 718 if not invalid.any():
Chris@87 719 return a
Chris@87 720 a._mask |= invalid
Chris@87 721 if fill_value is None:
Chris@87 722 fill_value = a.fill_value
Chris@87 723 a._data[invalid] = fill_value
Chris@87 724 return a
Chris@87 725
Chris@87 726
Chris@87 727
Chris@87 728 #####--------------------------------------------------------------------------
Chris@87 729 #---- --- Ufuncs ---
Chris@87 730 #####--------------------------------------------------------------------------
Chris@87 731 ufunc_domain = {}
Chris@87 732 ufunc_fills = {}
Chris@87 733
Chris@87 734 class _DomainCheckInterval:
Chris@87 735 """
Chris@87 736 Define a valid interval, so that :
Chris@87 737
Chris@87 738 ``domain_check_interval(a,b)(x) == True`` where
Chris@87 739 ``x < a`` or ``x > b``.
Chris@87 740
Chris@87 741 """
Chris@87 742 def __init__(self, a, b):
Chris@87 743 "domain_check_interval(a,b)(x) = true where x < a or y > b"
Chris@87 744 if (a > b):
Chris@87 745 (a, b) = (b, a)
Chris@87 746 self.a = a
Chris@87 747 self.b = b
Chris@87 748
Chris@87 749 def __call__ (self, x):
Chris@87 750 "Execute the call behavior."
Chris@87 751 return umath.logical_or(umath.greater (x, self.b),
Chris@87 752 umath.less(x, self.a))
Chris@87 753
Chris@87 754
Chris@87 755
Chris@87 756 class _DomainTan:
Chris@87 757 """Define a valid interval for the `tan` function, so that:
Chris@87 758
Chris@87 759 ``domain_tan(eps) = True`` where ``abs(cos(x)) < eps``
Chris@87 760
Chris@87 761 """
Chris@87 762 def __init__(self, eps):
Chris@87 763 "domain_tan(eps) = true where abs(cos(x)) < eps)"
Chris@87 764 self.eps = eps
Chris@87 765
Chris@87 766 def __call__ (self, x):
Chris@87 767 "Executes the call behavior."
Chris@87 768 return umath.less(umath.absolute(umath.cos(x)), self.eps)
Chris@87 769
Chris@87 770
Chris@87 771
Chris@87 772 class _DomainSafeDivide:
Chris@87 773 """Define a domain for safe division."""
Chris@87 774 def __init__ (self, tolerance=None):
Chris@87 775 self.tolerance = tolerance
Chris@87 776
Chris@87 777 def __call__ (self, a, b):
Chris@87 778 # Delay the selection of the tolerance to here in order to reduce numpy
Chris@87 779 # import times. The calculation of these parameters is a substantial
Chris@87 780 # component of numpy's import time.
Chris@87 781 if self.tolerance is None:
Chris@87 782 self.tolerance = np.finfo(float).tiny
Chris@87 783 # don't call ma ufuncs from __array_wrap__ which would fail for scalars
Chris@87 784 a, b = np.asarray(a), np.asarray(b)
Chris@87 785 return umath.absolute(a) * self.tolerance >= umath.absolute(b)
Chris@87 786
Chris@87 787
Chris@87 788
Chris@87 789 class _DomainGreater:
Chris@87 790 """DomainGreater(v)(x) is True where x <= v."""
Chris@87 791 def __init__(self, critical_value):
Chris@87 792 "DomainGreater(v)(x) = true where x <= v"
Chris@87 793 self.critical_value = critical_value
Chris@87 794
Chris@87 795 def __call__ (self, x):
Chris@87 796 "Executes the call behavior."
Chris@87 797 return umath.less_equal(x, self.critical_value)
Chris@87 798
Chris@87 799
Chris@87 800
Chris@87 801 class _DomainGreaterEqual:
Chris@87 802 """DomainGreaterEqual(v)(x) is True where x < v."""
Chris@87 803 def __init__(self, critical_value):
Chris@87 804 "DomainGreaterEqual(v)(x) = true where x < v"
Chris@87 805 self.critical_value = critical_value
Chris@87 806
Chris@87 807 def __call__ (self, x):
Chris@87 808 "Executes the call behavior."
Chris@87 809 return umath.less(x, self.critical_value)
Chris@87 810
Chris@87 811 #..............................................................................
Chris@87 812 class _MaskedUnaryOperation:
Chris@87 813 """
Chris@87 814 Defines masked version of unary operations, where invalid values are
Chris@87 815 pre-masked.
Chris@87 816
Chris@87 817 Parameters
Chris@87 818 ----------
Chris@87 819 mufunc : callable
Chris@87 820 The function for which to define a masked version. Made available
Chris@87 821 as ``_MaskedUnaryOperation.f``.
Chris@87 822 fill : scalar, optional
Chris@87 823 Filling value, default is 0.
Chris@87 824 domain : class instance
Chris@87 825 Domain for the function. Should be one of the ``_Domain*``
Chris@87 826 classes. Default is None.
Chris@87 827
Chris@87 828 """
Chris@87 829 def __init__ (self, mufunc, fill=0, domain=None):
Chris@87 830 """ _MaskedUnaryOperation(aufunc, fill=0, domain=None)
Chris@87 831 aufunc(fill) must be defined
Chris@87 832 self(x) returns aufunc(x)
Chris@87 833 with masked values where domain(x) is true or getmask(x) is true.
Chris@87 834 """
Chris@87 835 self.f = mufunc
Chris@87 836 self.fill = fill
Chris@87 837 self.domain = domain
Chris@87 838 self.__doc__ = getattr(mufunc, "__doc__", str(mufunc))
Chris@87 839 self.__name__ = getattr(mufunc, "__name__", str(mufunc))
Chris@87 840 ufunc_domain[mufunc] = domain
Chris@87 841 ufunc_fills[mufunc] = fill
Chris@87 842 #
Chris@87 843 def __call__ (self, a, *args, **kwargs):
Chris@87 844 "Execute the call behavior."
Chris@87 845 d = getdata(a)
Chris@87 846 # Case 1.1. : Domained function
Chris@87 847 if self.domain is not None:
Chris@87 848 with np.errstate(divide='ignore', invalid='ignore'):
Chris@87 849 result = self.f(d, *args, **kwargs)
Chris@87 850 # Make a mask
Chris@87 851 m = ~umath.isfinite(result)
Chris@87 852 m |= self.domain(d)
Chris@87 853 m |= getmask(a)
Chris@87 854 # Case 1.2. : Function without a domain
Chris@87 855 else:
Chris@87 856 # Get the result and the mask
Chris@87 857 result = self.f(d, *args, **kwargs)
Chris@87 858 m = getmask(a)
Chris@87 859 # Case 2.1. : The result is scalarscalar
Chris@87 860 if not result.ndim:
Chris@87 861 if m:
Chris@87 862 return masked
Chris@87 863 return result
Chris@87 864 # Case 2.2. The result is an array
Chris@87 865 # We need to fill the invalid data back w/ the input
Chris@87 866 # Now, that's plain silly: in C, we would just skip the element and keep
Chris@87 867 # the original, but we do have to do it that way in Python
Chris@87 868 if m is not nomask:
Chris@87 869 # In case result has a lower dtype than the inputs (as in equal)
Chris@87 870 try:
Chris@87 871 np.copyto(result, d, where=m)
Chris@87 872 except TypeError:
Chris@87 873 pass
Chris@87 874 # Transform to
Chris@87 875 if isinstance(a, MaskedArray):
Chris@87 876 subtype = type(a)
Chris@87 877 else:
Chris@87 878 subtype = MaskedArray
Chris@87 879 result = result.view(subtype)
Chris@87 880 result._mask = m
Chris@87 881 result._update_from(a)
Chris@87 882 return result
Chris@87 883 #
Chris@87 884 def __str__ (self):
Chris@87 885 return "Masked version of %s. [Invalid values are masked]" % str(self.f)
Chris@87 886
Chris@87 887
Chris@87 888
Chris@87 889 class _MaskedBinaryOperation:
Chris@87 890 """
Chris@87 891 Define masked version of binary operations, where invalid
Chris@87 892 values are pre-masked.
Chris@87 893
Chris@87 894 Parameters
Chris@87 895 ----------
Chris@87 896 mbfunc : function
Chris@87 897 The function for which to define a masked version. Made available
Chris@87 898 as ``_MaskedBinaryOperation.f``.
Chris@87 899 domain : class instance
Chris@87 900 Default domain for the function. Should be one of the ``_Domain*``
Chris@87 901 classes. Default is None.
Chris@87 902 fillx : scalar, optional
Chris@87 903 Filling value for the first argument, default is 0.
Chris@87 904 filly : scalar, optional
Chris@87 905 Filling value for the second argument, default is 0.
Chris@87 906
Chris@87 907 """
Chris@87 908 def __init__ (self, mbfunc, fillx=0, filly=0):
Chris@87 909 """abfunc(fillx, filly) must be defined.
Chris@87 910 abfunc(x, filly) = x for all x to enable reduce.
Chris@87 911 """
Chris@87 912 self.f = mbfunc
Chris@87 913 self.fillx = fillx
Chris@87 914 self.filly = filly
Chris@87 915 self.__doc__ = getattr(mbfunc, "__doc__", str(mbfunc))
Chris@87 916 self.__name__ = getattr(mbfunc, "__name__", str(mbfunc))
Chris@87 917 ufunc_domain[mbfunc] = None
Chris@87 918 ufunc_fills[mbfunc] = (fillx, filly)
Chris@87 919
Chris@87 920 def __call__ (self, a, b, *args, **kwargs):
Chris@87 921 "Execute the call behavior."
Chris@87 922 # Get the data, as ndarray
Chris@87 923 (da, db) = (getdata(a, subok=False), getdata(b, subok=False))
Chris@87 924 # Get the mask
Chris@87 925 (ma, mb) = (getmask(a), getmask(b))
Chris@87 926 if ma is nomask:
Chris@87 927 if mb is nomask:
Chris@87 928 m = nomask
Chris@87 929 else:
Chris@87 930 m = umath.logical_or(getmaskarray(a), mb)
Chris@87 931 elif mb is nomask:
Chris@87 932 m = umath.logical_or(ma, getmaskarray(b))
Chris@87 933 else:
Chris@87 934 m = umath.logical_or(ma, mb)
Chris@87 935 # Get the result
Chris@87 936 with np.errstate(divide='ignore', invalid='ignore'):
Chris@87 937 result = self.f(da, db, *args, **kwargs)
Chris@87 938 # check it worked
Chris@87 939 if result is NotImplemented:
Chris@87 940 return NotImplemented
Chris@87 941 # Case 1. : scalar
Chris@87 942 if not result.ndim:
Chris@87 943 if m:
Chris@87 944 return masked
Chris@87 945 return result
Chris@87 946 # Case 2. : array
Chris@87 947 # Revert result to da where masked
Chris@87 948 if m is not nomask:
Chris@87 949 np.copyto(result, da, casting='unsafe', where=m)
Chris@87 950 # Transforms to a (subclass of) MaskedArray
Chris@87 951 result = result.view(get_masked_subclass(a, b))
Chris@87 952 result._mask = m
Chris@87 953 # Update the optional info from the inputs
Chris@87 954 if isinstance(b, MaskedArray):
Chris@87 955 if isinstance(a, MaskedArray):
Chris@87 956 result._update_from(a)
Chris@87 957 else:
Chris@87 958 result._update_from(b)
Chris@87 959 elif isinstance(a, MaskedArray):
Chris@87 960 result._update_from(a)
Chris@87 961 return result
Chris@87 962
Chris@87 963
Chris@87 964 def reduce(self, target, axis=0, dtype=None):
Chris@87 965 """Reduce `target` along the given `axis`."""
Chris@87 966 if isinstance(target, MaskedArray):
Chris@87 967 tclass = type(target)
Chris@87 968 else:
Chris@87 969 tclass = MaskedArray
Chris@87 970 m = getmask(target)
Chris@87 971 t = filled(target, self.filly)
Chris@87 972 if t.shape == ():
Chris@87 973 t = t.reshape(1)
Chris@87 974 if m is not nomask:
Chris@87 975 m = make_mask(m, copy=1)
Chris@87 976 m.shape = (1,)
Chris@87 977 if m is nomask:
Chris@87 978 return self.f.reduce(t, axis).view(tclass)
Chris@87 979 t = t.view(tclass)
Chris@87 980 t._mask = m
Chris@87 981 tr = self.f.reduce(getdata(t), axis, dtype=dtype or t.dtype)
Chris@87 982 mr = umath.logical_and.reduce(m, axis)
Chris@87 983 tr = tr.view(tclass)
Chris@87 984 if mr.ndim > 0:
Chris@87 985 tr._mask = mr
Chris@87 986 return tr
Chris@87 987 elif mr:
Chris@87 988 return masked
Chris@87 989 return tr
Chris@87 990
Chris@87 991 def outer (self, a, b):
Chris@87 992 """Return the function applied to the outer product of a and b.
Chris@87 993
Chris@87 994 """
Chris@87 995 ma = getmask(a)
Chris@87 996 mb = getmask(b)
Chris@87 997 if ma is nomask and mb is nomask:
Chris@87 998 m = nomask
Chris@87 999 else:
Chris@87 1000 ma = getmaskarray(a)
Chris@87 1001 mb = getmaskarray(b)
Chris@87 1002 m = umath.logical_or.outer(ma, mb)
Chris@87 1003 if (not m.ndim) and m:
Chris@87 1004 return masked
Chris@87 1005 (da, db) = (getdata(a), getdata(b))
Chris@87 1006 d = self.f.outer(da, db)
Chris@87 1007 # check it worked
Chris@87 1008 if d is NotImplemented:
Chris@87 1009 return NotImplemented
Chris@87 1010 if m is not nomask:
Chris@87 1011 np.copyto(d, da, where=m)
Chris@87 1012 if d.shape:
Chris@87 1013 d = d.view(get_masked_subclass(a, b))
Chris@87 1014 d._mask = m
Chris@87 1015 return d
Chris@87 1016
Chris@87 1017 def accumulate (self, target, axis=0):
Chris@87 1018 """Accumulate `target` along `axis` after filling with y fill
Chris@87 1019 value.
Chris@87 1020
Chris@87 1021 """
Chris@87 1022 if isinstance(target, MaskedArray):
Chris@87 1023 tclass = type(target)
Chris@87 1024 else:
Chris@87 1025 tclass = MaskedArray
Chris@87 1026 t = filled(target, self.filly)
Chris@87 1027 return self.f.accumulate(t, axis).view(tclass)
Chris@87 1028
Chris@87 1029 def __str__ (self):
Chris@87 1030 return "Masked version of " + str(self.f)
Chris@87 1031
Chris@87 1032
Chris@87 1033
Chris@87 1034 class _DomainedBinaryOperation:
Chris@87 1035 """
Chris@87 1036 Define binary operations that have a domain, like divide.
Chris@87 1037
Chris@87 1038 They have no reduce, outer or accumulate.
Chris@87 1039
Chris@87 1040 Parameters
Chris@87 1041 ----------
Chris@87 1042 mbfunc : function
Chris@87 1043 The function for which to define a masked version. Made available
Chris@87 1044 as ``_DomainedBinaryOperation.f``.
Chris@87 1045 domain : class instance
Chris@87 1046 Default domain for the function. Should be one of the ``_Domain*``
Chris@87 1047 classes.
Chris@87 1048 fillx : scalar, optional
Chris@87 1049 Filling value for the first argument, default is 0.
Chris@87 1050 filly : scalar, optional
Chris@87 1051 Filling value for the second argument, default is 0.
Chris@87 1052
Chris@87 1053 """
Chris@87 1054 def __init__ (self, dbfunc, domain, fillx=0, filly=0):
Chris@87 1055 """abfunc(fillx, filly) must be defined.
Chris@87 1056 abfunc(x, filly) = x for all x to enable reduce.
Chris@87 1057 """
Chris@87 1058 self.f = dbfunc
Chris@87 1059 self.domain = domain
Chris@87 1060 self.fillx = fillx
Chris@87 1061 self.filly = filly
Chris@87 1062 self.__doc__ = getattr(dbfunc, "__doc__", str(dbfunc))
Chris@87 1063 self.__name__ = getattr(dbfunc, "__name__", str(dbfunc))
Chris@87 1064 ufunc_domain[dbfunc] = domain
Chris@87 1065 ufunc_fills[dbfunc] = (fillx, filly)
Chris@87 1066
Chris@87 1067 def __call__(self, a, b, *args, **kwargs):
Chris@87 1068 "Execute the call behavior."
Chris@87 1069 # Get the data and the mask
Chris@87 1070 (da, db) = (getdata(a, subok=False), getdata(b, subok=False))
Chris@87 1071 (ma, mb) = (getmask(a), getmask(b))
Chris@87 1072 # Get the result
Chris@87 1073 with np.errstate(divide='ignore', invalid='ignore'):
Chris@87 1074 result = self.f(da, db, *args, **kwargs)
Chris@87 1075 # check it worked
Chris@87 1076 if result is NotImplemented:
Chris@87 1077 return NotImplemented
Chris@87 1078 # Get the mask as a combination of ma, mb and invalid
Chris@87 1079 m = ~umath.isfinite(result)
Chris@87 1080 m |= ma
Chris@87 1081 m |= mb
Chris@87 1082 # Apply the domain
Chris@87 1083 domain = ufunc_domain.get(self.f, None)
Chris@87 1084 if domain is not None:
Chris@87 1085 m |= filled(domain(da, db), True)
Chris@87 1086 # Take care of the scalar case first
Chris@87 1087 if (not m.ndim):
Chris@87 1088 if m:
Chris@87 1089 return masked
Chris@87 1090 else:
Chris@87 1091 return result
Chris@87 1092 # When the mask is True, put back da
Chris@87 1093 np.copyto(result, da, casting='unsafe', where=m)
Chris@87 1094 result = result.view(get_masked_subclass(a, b))
Chris@87 1095 result._mask = m
Chris@87 1096 if isinstance(b, MaskedArray):
Chris@87 1097 if isinstance(a, MaskedArray):
Chris@87 1098 result._update_from(a)
Chris@87 1099 else:
Chris@87 1100 result._update_from(b)
Chris@87 1101 elif isinstance(a, MaskedArray):
Chris@87 1102 result._update_from(a)
Chris@87 1103 return result
Chris@87 1104
Chris@87 1105 def __str__ (self):
Chris@87 1106 return "Masked version of " + str(self.f)
Chris@87 1107
Chris@87 1108 #..............................................................................
Chris@87 1109 # Unary ufuncs
Chris@87 1110 exp = _MaskedUnaryOperation(umath.exp)
Chris@87 1111 conjugate = _MaskedUnaryOperation(umath.conjugate)
Chris@87 1112 sin = _MaskedUnaryOperation(umath.sin)
Chris@87 1113 cos = _MaskedUnaryOperation(umath.cos)
Chris@87 1114 tan = _MaskedUnaryOperation(umath.tan)
Chris@87 1115 arctan = _MaskedUnaryOperation(umath.arctan)
Chris@87 1116 arcsinh = _MaskedUnaryOperation(umath.arcsinh)
Chris@87 1117 sinh = _MaskedUnaryOperation(umath.sinh)
Chris@87 1118 cosh = _MaskedUnaryOperation(umath.cosh)
Chris@87 1119 tanh = _MaskedUnaryOperation(umath.tanh)
Chris@87 1120 abs = absolute = _MaskedUnaryOperation(umath.absolute)
Chris@87 1121 angle = _MaskedUnaryOperation(angle) # from numpy.lib.function_base
Chris@87 1122 fabs = _MaskedUnaryOperation(umath.fabs)
Chris@87 1123 negative = _MaskedUnaryOperation(umath.negative)
Chris@87 1124 floor = _MaskedUnaryOperation(umath.floor)
Chris@87 1125 ceil = _MaskedUnaryOperation(umath.ceil)
Chris@87 1126 around = _MaskedUnaryOperation(np.round_)
Chris@87 1127 logical_not = _MaskedUnaryOperation(umath.logical_not)
Chris@87 1128 # Domained unary ufuncs .......................................................
Chris@87 1129 sqrt = _MaskedUnaryOperation(umath.sqrt, 0.0,
Chris@87 1130 _DomainGreaterEqual(0.0))
Chris@87 1131 log = _MaskedUnaryOperation(umath.log, 1.0,
Chris@87 1132 _DomainGreater(0.0))
Chris@87 1133 log2 = _MaskedUnaryOperation(umath.log2, 1.0,
Chris@87 1134 _DomainGreater(0.0))
Chris@87 1135 log10 = _MaskedUnaryOperation(umath.log10, 1.0,
Chris@87 1136 _DomainGreater(0.0))
Chris@87 1137 tan = _MaskedUnaryOperation(umath.tan, 0.0,
Chris@87 1138 _DomainTan(1e-35))
Chris@87 1139 arcsin = _MaskedUnaryOperation(umath.arcsin, 0.0,
Chris@87 1140 _DomainCheckInterval(-1.0, 1.0))
Chris@87 1141 arccos = _MaskedUnaryOperation(umath.arccos, 0.0,
Chris@87 1142 _DomainCheckInterval(-1.0, 1.0))
Chris@87 1143 arccosh = _MaskedUnaryOperation(umath.arccosh, 1.0,
Chris@87 1144 _DomainGreaterEqual(1.0))
Chris@87 1145 arctanh = _MaskedUnaryOperation(umath.arctanh, 0.0,
Chris@87 1146 _DomainCheckInterval(-1.0 + 1e-15, 1.0 - 1e-15))
Chris@87 1147 # Binary ufuncs ...............................................................
Chris@87 1148 add = _MaskedBinaryOperation(umath.add)
Chris@87 1149 subtract = _MaskedBinaryOperation(umath.subtract)
Chris@87 1150 multiply = _MaskedBinaryOperation(umath.multiply, 1, 1)
Chris@87 1151 arctan2 = _MaskedBinaryOperation(umath.arctan2, 0.0, 1.0)
Chris@87 1152 equal = _MaskedBinaryOperation(umath.equal)
Chris@87 1153 equal.reduce = None
Chris@87 1154 not_equal = _MaskedBinaryOperation(umath.not_equal)
Chris@87 1155 not_equal.reduce = None
Chris@87 1156 less_equal = _MaskedBinaryOperation(umath.less_equal)
Chris@87 1157 less_equal.reduce = None
Chris@87 1158 greater_equal = _MaskedBinaryOperation(umath.greater_equal)
Chris@87 1159 greater_equal.reduce = None
Chris@87 1160 less = _MaskedBinaryOperation(umath.less)
Chris@87 1161 less.reduce = None
Chris@87 1162 greater = _MaskedBinaryOperation(umath.greater)
Chris@87 1163 greater.reduce = None
Chris@87 1164 logical_and = _MaskedBinaryOperation(umath.logical_and)
Chris@87 1165 alltrue = _MaskedBinaryOperation(umath.logical_and, 1, 1).reduce
Chris@87 1166 logical_or = _MaskedBinaryOperation(umath.logical_or)
Chris@87 1167 sometrue = logical_or.reduce
Chris@87 1168 logical_xor = _MaskedBinaryOperation(umath.logical_xor)
Chris@87 1169 bitwise_and = _MaskedBinaryOperation(umath.bitwise_and)
Chris@87 1170 bitwise_or = _MaskedBinaryOperation(umath.bitwise_or)
Chris@87 1171 bitwise_xor = _MaskedBinaryOperation(umath.bitwise_xor)
Chris@87 1172 hypot = _MaskedBinaryOperation(umath.hypot)
Chris@87 1173 # Domained binary ufuncs ......................................................
Chris@87 1174 divide = _DomainedBinaryOperation(umath.divide, _DomainSafeDivide(), 0, 1)
Chris@87 1175 true_divide = _DomainedBinaryOperation(umath.true_divide,
Chris@87 1176 _DomainSafeDivide(), 0, 1)
Chris@87 1177 floor_divide = _DomainedBinaryOperation(umath.floor_divide,
Chris@87 1178 _DomainSafeDivide(), 0, 1)
Chris@87 1179 remainder = _DomainedBinaryOperation(umath.remainder,
Chris@87 1180 _DomainSafeDivide(), 0, 1)
Chris@87 1181 fmod = _DomainedBinaryOperation(umath.fmod, _DomainSafeDivide(), 0, 1)
Chris@87 1182 mod = _DomainedBinaryOperation(umath.mod, _DomainSafeDivide(), 0, 1)
Chris@87 1183
Chris@87 1184
Chris@87 1185 #####--------------------------------------------------------------------------
Chris@87 1186 #---- --- Mask creation functions ---
Chris@87 1187 #####--------------------------------------------------------------------------
Chris@87 1188
Chris@87 1189 def _recursive_make_descr(datatype, newtype=bool_):
Chris@87 1190 "Private function allowing recursion in make_descr."
Chris@87 1191 # Do we have some name fields ?
Chris@87 1192 if datatype.names:
Chris@87 1193 descr = []
Chris@87 1194 for name in datatype.names:
Chris@87 1195 field = datatype.fields[name]
Chris@87 1196 if len(field) == 3:
Chris@87 1197 # Prepend the title to the name
Chris@87 1198 name = (field[-1], name)
Chris@87 1199 descr.append((name, _recursive_make_descr(field[0], newtype)))
Chris@87 1200 return descr
Chris@87 1201 # Is this some kind of composite a la (np.float,2)
Chris@87 1202 elif datatype.subdtype:
Chris@87 1203 mdescr = list(datatype.subdtype)
Chris@87 1204 mdescr[0] = newtype
Chris@87 1205 return tuple(mdescr)
Chris@87 1206 else:
Chris@87 1207 return newtype
Chris@87 1208
Chris@87 1209 def make_mask_descr(ndtype):
Chris@87 1210 """
Chris@87 1211 Construct a dtype description list from a given dtype.
Chris@87 1212
Chris@87 1213 Returns a new dtype object, with the type of all fields in `ndtype` to a
Chris@87 1214 boolean type. Field names are not altered.
Chris@87 1215
Chris@87 1216 Parameters
Chris@87 1217 ----------
Chris@87 1218 ndtype : dtype
Chris@87 1219 The dtype to convert.
Chris@87 1220
Chris@87 1221 Returns
Chris@87 1222 -------
Chris@87 1223 result : dtype
Chris@87 1224 A dtype that looks like `ndtype`, the type of all fields is boolean.
Chris@87 1225
Chris@87 1226 Examples
Chris@87 1227 --------
Chris@87 1228 >>> import numpy.ma as ma
Chris@87 1229 >>> dtype = np.dtype({'names':['foo', 'bar'],
Chris@87 1230 'formats':[np.float32, np.int]})
Chris@87 1231 >>> dtype
Chris@87 1232 dtype([('foo', '<f4'), ('bar', '<i4')])
Chris@87 1233 >>> ma.make_mask_descr(dtype)
Chris@87 1234 dtype([('foo', '|b1'), ('bar', '|b1')])
Chris@87 1235 >>> ma.make_mask_descr(np.float32)
Chris@87 1236 <type 'numpy.bool_'>
Chris@87 1237
Chris@87 1238 """
Chris@87 1239 # Make sure we do have a dtype
Chris@87 1240 if not isinstance(ndtype, np.dtype):
Chris@87 1241 ndtype = np.dtype(ndtype)
Chris@87 1242 return np.dtype(_recursive_make_descr(ndtype, np.bool))
Chris@87 1243
Chris@87 1244 def getmask(a):
Chris@87 1245 """
Chris@87 1246 Return the mask of a masked array, or nomask.
Chris@87 1247
Chris@87 1248 Return the mask of `a` as an ndarray if `a` is a `MaskedArray` and the
Chris@87 1249 mask is not `nomask`, else return `nomask`. To guarantee a full array
Chris@87 1250 of booleans of the same shape as a, use `getmaskarray`.
Chris@87 1251
Chris@87 1252 Parameters
Chris@87 1253 ----------
Chris@87 1254 a : array_like
Chris@87 1255 Input `MaskedArray` for which the mask is required.
Chris@87 1256
Chris@87 1257 See Also
Chris@87 1258 --------
Chris@87 1259 getdata : Return the data of a masked array as an ndarray.
Chris@87 1260 getmaskarray : Return the mask of a masked array, or full array of False.
Chris@87 1261
Chris@87 1262 Examples
Chris@87 1263 --------
Chris@87 1264 >>> import numpy.ma as ma
Chris@87 1265 >>> a = ma.masked_equal([[1,2],[3,4]], 2)
Chris@87 1266 >>> a
Chris@87 1267 masked_array(data =
Chris@87 1268 [[1 --]
Chris@87 1269 [3 4]],
Chris@87 1270 mask =
Chris@87 1271 [[False True]
Chris@87 1272 [False False]],
Chris@87 1273 fill_value=999999)
Chris@87 1274 >>> ma.getmask(a)
Chris@87 1275 array([[False, True],
Chris@87 1276 [False, False]], dtype=bool)
Chris@87 1277
Chris@87 1278 Equivalently use the `MaskedArray` `mask` attribute.
Chris@87 1279
Chris@87 1280 >>> a.mask
Chris@87 1281 array([[False, True],
Chris@87 1282 [False, False]], dtype=bool)
Chris@87 1283
Chris@87 1284 Result when mask == `nomask`
Chris@87 1285
Chris@87 1286 >>> b = ma.masked_array([[1,2],[3,4]])
Chris@87 1287 >>> b
Chris@87 1288 masked_array(data =
Chris@87 1289 [[1 2]
Chris@87 1290 [3 4]],
Chris@87 1291 mask =
Chris@87 1292 False,
Chris@87 1293 fill_value=999999)
Chris@87 1294 >>> ma.nomask
Chris@87 1295 False
Chris@87 1296 >>> ma.getmask(b) == ma.nomask
Chris@87 1297 True
Chris@87 1298 >>> b.mask == ma.nomask
Chris@87 1299 True
Chris@87 1300
Chris@87 1301 """
Chris@87 1302 return getattr(a, '_mask', nomask)
Chris@87 1303 get_mask = getmask
Chris@87 1304
Chris@87 1305 def getmaskarray(arr):
Chris@87 1306 """
Chris@87 1307 Return the mask of a masked array, or full boolean array of False.
Chris@87 1308
Chris@87 1309 Return the mask of `arr` as an ndarray if `arr` is a `MaskedArray` and
Chris@87 1310 the mask is not `nomask`, else return a full boolean array of False of
Chris@87 1311 the same shape as `arr`.
Chris@87 1312
Chris@87 1313 Parameters
Chris@87 1314 ----------
Chris@87 1315 arr : array_like
Chris@87 1316 Input `MaskedArray` for which the mask is required.
Chris@87 1317
Chris@87 1318 See Also
Chris@87 1319 --------
Chris@87 1320 getmask : Return the mask of a masked array, or nomask.
Chris@87 1321 getdata : Return the data of a masked array as an ndarray.
Chris@87 1322
Chris@87 1323 Examples
Chris@87 1324 --------
Chris@87 1325 >>> import numpy.ma as ma
Chris@87 1326 >>> a = ma.masked_equal([[1,2],[3,4]], 2)
Chris@87 1327 >>> a
Chris@87 1328 masked_array(data =
Chris@87 1329 [[1 --]
Chris@87 1330 [3 4]],
Chris@87 1331 mask =
Chris@87 1332 [[False True]
Chris@87 1333 [False False]],
Chris@87 1334 fill_value=999999)
Chris@87 1335 >>> ma.getmaskarray(a)
Chris@87 1336 array([[False, True],
Chris@87 1337 [False, False]], dtype=bool)
Chris@87 1338
Chris@87 1339 Result when mask == ``nomask``
Chris@87 1340
Chris@87 1341 >>> b = ma.masked_array([[1,2],[3,4]])
Chris@87 1342 >>> b
Chris@87 1343 masked_array(data =
Chris@87 1344 [[1 2]
Chris@87 1345 [3 4]],
Chris@87 1346 mask =
Chris@87 1347 False,
Chris@87 1348 fill_value=999999)
Chris@87 1349 >>> >ma.getmaskarray(b)
Chris@87 1350 array([[False, False],
Chris@87 1351 [False, False]], dtype=bool)
Chris@87 1352
Chris@87 1353 """
Chris@87 1354 mask = getmask(arr)
Chris@87 1355 if mask is nomask:
Chris@87 1356 mask = make_mask_none(np.shape(arr), getdata(arr).dtype)
Chris@87 1357 return mask
Chris@87 1358
Chris@87 1359 def is_mask(m):
Chris@87 1360 """
Chris@87 1361 Return True if m is a valid, standard mask.
Chris@87 1362
Chris@87 1363 This function does not check the contents of the input, only that the
Chris@87 1364 type is MaskType. In particular, this function returns False if the
Chris@87 1365 mask has a flexible dtype.
Chris@87 1366
Chris@87 1367 Parameters
Chris@87 1368 ----------
Chris@87 1369 m : array_like
Chris@87 1370 Array to test.
Chris@87 1371
Chris@87 1372 Returns
Chris@87 1373 -------
Chris@87 1374 result : bool
Chris@87 1375 True if `m.dtype.type` is MaskType, False otherwise.
Chris@87 1376
Chris@87 1377 See Also
Chris@87 1378 --------
Chris@87 1379 isMaskedArray : Test whether input is an instance of MaskedArray.
Chris@87 1380
Chris@87 1381 Examples
Chris@87 1382 --------
Chris@87 1383 >>> import numpy.ma as ma
Chris@87 1384 >>> m = ma.masked_equal([0, 1, 0, 2, 3], 0)
Chris@87 1385 >>> m
Chris@87 1386 masked_array(data = [-- 1 -- 2 3],
Chris@87 1387 mask = [ True False True False False],
Chris@87 1388 fill_value=999999)
Chris@87 1389 >>> ma.is_mask(m)
Chris@87 1390 False
Chris@87 1391 >>> ma.is_mask(m.mask)
Chris@87 1392 True
Chris@87 1393
Chris@87 1394 Input must be an ndarray (or have similar attributes)
Chris@87 1395 for it to be considered a valid mask.
Chris@87 1396
Chris@87 1397 >>> m = [False, True, False]
Chris@87 1398 >>> ma.is_mask(m)
Chris@87 1399 False
Chris@87 1400 >>> m = np.array([False, True, False])
Chris@87 1401 >>> m
Chris@87 1402 array([False, True, False], dtype=bool)
Chris@87 1403 >>> ma.is_mask(m)
Chris@87 1404 True
Chris@87 1405
Chris@87 1406 Arrays with complex dtypes don't return True.
Chris@87 1407
Chris@87 1408 >>> dtype = np.dtype({'names':['monty', 'pithon'],
Chris@87 1409 'formats':[np.bool, np.bool]})
Chris@87 1410 >>> dtype
Chris@87 1411 dtype([('monty', '|b1'), ('pithon', '|b1')])
Chris@87 1412 >>> m = np.array([(True, False), (False, True), (True, False)],
Chris@87 1413 dtype=dtype)
Chris@87 1414 >>> m
Chris@87 1415 array([(True, False), (False, True), (True, False)],
Chris@87 1416 dtype=[('monty', '|b1'), ('pithon', '|b1')])
Chris@87 1417 >>> ma.is_mask(m)
Chris@87 1418 False
Chris@87 1419
Chris@87 1420 """
Chris@87 1421 try:
Chris@87 1422 return m.dtype.type is MaskType
Chris@87 1423 except AttributeError:
Chris@87 1424 return False
Chris@87 1425
Chris@87 1426 def make_mask(m, copy=False, shrink=True, dtype=MaskType):
Chris@87 1427 """
Chris@87 1428 Create a boolean mask from an array.
Chris@87 1429
Chris@87 1430 Return `m` as a boolean mask, creating a copy if necessary or requested.
Chris@87 1431 The function can accept any sequence that is convertible to integers,
Chris@87 1432 or ``nomask``. Does not require that contents must be 0s and 1s, values
Chris@87 1433 of 0 are interepreted as False, everything else as True.
Chris@87 1434
Chris@87 1435 Parameters
Chris@87 1436 ----------
Chris@87 1437 m : array_like
Chris@87 1438 Potential mask.
Chris@87 1439 copy : bool, optional
Chris@87 1440 Whether to return a copy of `m` (True) or `m` itself (False).
Chris@87 1441 shrink : bool, optional
Chris@87 1442 Whether to shrink `m` to ``nomask`` if all its values are False.
Chris@87 1443 dtype : dtype, optional
Chris@87 1444 Data-type of the output mask. By default, the output mask has
Chris@87 1445 a dtype of MaskType (bool). If the dtype is flexible, each field
Chris@87 1446 has a boolean dtype.
Chris@87 1447
Chris@87 1448 Returns
Chris@87 1449 -------
Chris@87 1450 result : ndarray
Chris@87 1451 A boolean mask derived from `m`.
Chris@87 1452
Chris@87 1453 Examples
Chris@87 1454 --------
Chris@87 1455 >>> import numpy.ma as ma
Chris@87 1456 >>> m = [True, False, True, True]
Chris@87 1457 >>> ma.make_mask(m)
Chris@87 1458 array([ True, False, True, True], dtype=bool)
Chris@87 1459 >>> m = [1, 0, 1, 1]
Chris@87 1460 >>> ma.make_mask(m)
Chris@87 1461 array([ True, False, True, True], dtype=bool)
Chris@87 1462 >>> m = [1, 0, 2, -3]
Chris@87 1463 >>> ma.make_mask(m)
Chris@87 1464 array([ True, False, True, True], dtype=bool)
Chris@87 1465
Chris@87 1466 Effect of the `shrink` parameter.
Chris@87 1467
Chris@87 1468 >>> m = np.zeros(4)
Chris@87 1469 >>> m
Chris@87 1470 array([ 0., 0., 0., 0.])
Chris@87 1471 >>> ma.make_mask(m)
Chris@87 1472 False
Chris@87 1473 >>> ma.make_mask(m, shrink=False)
Chris@87 1474 array([False, False, False, False], dtype=bool)
Chris@87 1475
Chris@87 1476 Using a flexible `dtype`.
Chris@87 1477
Chris@87 1478 >>> m = [1, 0, 1, 1]
Chris@87 1479 >>> n = [0, 1, 0, 0]
Chris@87 1480 >>> arr = []
Chris@87 1481 >>> for man, mouse in zip(m, n):
Chris@87 1482 ... arr.append((man, mouse))
Chris@87 1483 >>> arr
Chris@87 1484 [(1, 0), (0, 1), (1, 0), (1, 0)]
Chris@87 1485 >>> dtype = np.dtype({'names':['man', 'mouse'],
Chris@87 1486 'formats':[np.int, np.int]})
Chris@87 1487 >>> arr = np.array(arr, dtype=dtype)
Chris@87 1488 >>> arr
Chris@87 1489 array([(1, 0), (0, 1), (1, 0), (1, 0)],
Chris@87 1490 dtype=[('man', '<i4'), ('mouse', '<i4')])
Chris@87 1491 >>> ma.make_mask(arr, dtype=dtype)
Chris@87 1492 array([(True, False), (False, True), (True, False), (True, False)],
Chris@87 1493 dtype=[('man', '|b1'), ('mouse', '|b1')])
Chris@87 1494
Chris@87 1495 """
Chris@87 1496 if m is nomask:
Chris@87 1497 return nomask
Chris@87 1498 elif isinstance(m, ndarray):
Chris@87 1499 # We won't return after this point to make sure we can shrink the mask
Chris@87 1500 # Fill the mask in case there are missing data
Chris@87 1501 m = filled(m, True)
Chris@87 1502 # Make sure the input dtype is valid
Chris@87 1503 dtype = make_mask_descr(dtype)
Chris@87 1504 if m.dtype == dtype:
Chris@87 1505 if copy:
Chris@87 1506 result = m.copy()
Chris@87 1507 else:
Chris@87 1508 result = m
Chris@87 1509 else:
Chris@87 1510 result = np.array(m, dtype=dtype, copy=copy)
Chris@87 1511 else:
Chris@87 1512 result = np.array(filled(m, True), dtype=MaskType)
Chris@87 1513 # Bas les masques !
Chris@87 1514 if shrink and (not result.dtype.names) and (not result.any()):
Chris@87 1515 return nomask
Chris@87 1516 else:
Chris@87 1517 return result
Chris@87 1518
Chris@87 1519
Chris@87 1520 def make_mask_none(newshape, dtype=None):
Chris@87 1521 """
Chris@87 1522 Return a boolean mask of the given shape, filled with False.
Chris@87 1523
Chris@87 1524 This function returns a boolean ndarray with all entries False, that can
Chris@87 1525 be used in common mask manipulations. If a complex dtype is specified, the
Chris@87 1526 type of each field is converted to a boolean type.
Chris@87 1527
Chris@87 1528 Parameters
Chris@87 1529 ----------
Chris@87 1530 newshape : tuple
Chris@87 1531 A tuple indicating the shape of the mask.
Chris@87 1532 dtype : {None, dtype}, optional
Chris@87 1533 If None, use a MaskType instance. Otherwise, use a new datatype with
Chris@87 1534 the same fields as `dtype`, converted to boolean types.
Chris@87 1535
Chris@87 1536 Returns
Chris@87 1537 -------
Chris@87 1538 result : ndarray
Chris@87 1539 An ndarray of appropriate shape and dtype, filled with False.
Chris@87 1540
Chris@87 1541 See Also
Chris@87 1542 --------
Chris@87 1543 make_mask : Create a boolean mask from an array.
Chris@87 1544 make_mask_descr : Construct a dtype description list from a given dtype.
Chris@87 1545
Chris@87 1546 Examples
Chris@87 1547 --------
Chris@87 1548 >>> import numpy.ma as ma
Chris@87 1549 >>> ma.make_mask_none((3,))
Chris@87 1550 array([False, False, False], dtype=bool)
Chris@87 1551
Chris@87 1552 Defining a more complex dtype.
Chris@87 1553
Chris@87 1554 >>> dtype = np.dtype({'names':['foo', 'bar'],
Chris@87 1555 'formats':[np.float32, np.int]})
Chris@87 1556 >>> dtype
Chris@87 1557 dtype([('foo', '<f4'), ('bar', '<i4')])
Chris@87 1558 >>> ma.make_mask_none((3,), dtype=dtype)
Chris@87 1559 array([(False, False), (False, False), (False, False)],
Chris@87 1560 dtype=[('foo', '|b1'), ('bar', '|b1')])
Chris@87 1561
Chris@87 1562 """
Chris@87 1563 if dtype is None:
Chris@87 1564 result = np.zeros(newshape, dtype=MaskType)
Chris@87 1565 else:
Chris@87 1566 result = np.zeros(newshape, dtype=make_mask_descr(dtype))
Chris@87 1567 return result
Chris@87 1568
Chris@87 1569 def mask_or (m1, m2, copy=False, shrink=True):
Chris@87 1570 """
Chris@87 1571 Combine two masks with the ``logical_or`` operator.
Chris@87 1572
Chris@87 1573 The result may be a view on `m1` or `m2` if the other is `nomask`
Chris@87 1574 (i.e. False).
Chris@87 1575
Chris@87 1576 Parameters
Chris@87 1577 ----------
Chris@87 1578 m1, m2 : array_like
Chris@87 1579 Input masks.
Chris@87 1580 copy : bool, optional
Chris@87 1581 If copy is False and one of the inputs is `nomask`, return a view
Chris@87 1582 of the other input mask. Defaults to False.
Chris@87 1583 shrink : bool, optional
Chris@87 1584 Whether to shrink the output to `nomask` if all its values are
Chris@87 1585 False. Defaults to True.
Chris@87 1586
Chris@87 1587 Returns
Chris@87 1588 -------
Chris@87 1589 mask : output mask
Chris@87 1590 The result masks values that are masked in either `m1` or `m2`.
Chris@87 1591
Chris@87 1592 Raises
Chris@87 1593 ------
Chris@87 1594 ValueError
Chris@87 1595 If `m1` and `m2` have different flexible dtypes.
Chris@87 1596
Chris@87 1597 Examples
Chris@87 1598 --------
Chris@87 1599 >>> m1 = np.ma.make_mask([0, 1, 1, 0])
Chris@87 1600 >>> m2 = np.ma.make_mask([1, 0, 0, 0])
Chris@87 1601 >>> np.ma.mask_or(m1, m2)
Chris@87 1602 array([ True, True, True, False], dtype=bool)
Chris@87 1603
Chris@87 1604 """
Chris@87 1605 def _recursive_mask_or(m1, m2, newmask):
Chris@87 1606 names = m1.dtype.names
Chris@87 1607 for name in names:
Chris@87 1608 current1 = m1[name]
Chris@87 1609 if current1.dtype.names:
Chris@87 1610 _recursive_mask_or(current1, m2[name], newmask[name])
Chris@87 1611 else:
Chris@87 1612 umath.logical_or(current1, m2[name], newmask[name])
Chris@87 1613 return
Chris@87 1614 #
Chris@87 1615 if (m1 is nomask) or (m1 is False):
Chris@87 1616 dtype = getattr(m2, 'dtype', MaskType)
Chris@87 1617 return make_mask(m2, copy=copy, shrink=shrink, dtype=dtype)
Chris@87 1618 if (m2 is nomask) or (m2 is False):
Chris@87 1619 dtype = getattr(m1, 'dtype', MaskType)
Chris@87 1620 return make_mask(m1, copy=copy, shrink=shrink, dtype=dtype)
Chris@87 1621 if m1 is m2 and is_mask(m1):
Chris@87 1622 return m1
Chris@87 1623 (dtype1, dtype2) = (getattr(m1, 'dtype', None), getattr(m2, 'dtype', None))
Chris@87 1624 if (dtype1 != dtype2):
Chris@87 1625 raise ValueError("Incompatible dtypes '%s'<>'%s'" % (dtype1, dtype2))
Chris@87 1626 if dtype1.names:
Chris@87 1627 newmask = np.empty_like(m1)
Chris@87 1628 _recursive_mask_or(m1, m2, newmask)
Chris@87 1629 return newmask
Chris@87 1630 return make_mask(umath.logical_or(m1, m2), copy=copy, shrink=shrink)
Chris@87 1631
Chris@87 1632
Chris@87 1633 def flatten_mask(mask):
Chris@87 1634 """
Chris@87 1635 Returns a completely flattened version of the mask, where nested fields
Chris@87 1636 are collapsed.
Chris@87 1637
Chris@87 1638 Parameters
Chris@87 1639 ----------
Chris@87 1640 mask : array_like
Chris@87 1641 Input array, which will be interpreted as booleans.
Chris@87 1642
Chris@87 1643 Returns
Chris@87 1644 -------
Chris@87 1645 flattened_mask : ndarray of bools
Chris@87 1646 The flattened input.
Chris@87 1647
Chris@87 1648 Examples
Chris@87 1649 --------
Chris@87 1650 >>> mask = np.array([0, 0, 1], dtype=np.bool)
Chris@87 1651 >>> flatten_mask(mask)
Chris@87 1652 array([False, False, True], dtype=bool)
Chris@87 1653
Chris@87 1654 >>> mask = np.array([(0, 0), (0, 1)], dtype=[('a', bool), ('b', bool)])
Chris@87 1655 >>> flatten_mask(mask)
Chris@87 1656 array([False, False, False, True], dtype=bool)
Chris@87 1657
Chris@87 1658 >>> mdtype = [('a', bool), ('b', [('ba', bool), ('bb', bool)])]
Chris@87 1659 >>> mask = np.array([(0, (0, 0)), (0, (0, 1))], dtype=mdtype)
Chris@87 1660 >>> flatten_mask(mask)
Chris@87 1661 array([False, False, False, False, False, True], dtype=bool)
Chris@87 1662
Chris@87 1663 """
Chris@87 1664 #
Chris@87 1665 def _flatmask(mask):
Chris@87 1666 "Flatten the mask and returns a (maybe nested) sequence of booleans."
Chris@87 1667 mnames = mask.dtype.names
Chris@87 1668 if mnames:
Chris@87 1669 return [flatten_mask(mask[name]) for name in mnames]
Chris@87 1670 else:
Chris@87 1671 return mask
Chris@87 1672 #
Chris@87 1673 def _flatsequence(sequence):
Chris@87 1674 "Generates a flattened version of the sequence."
Chris@87 1675 try:
Chris@87 1676 for element in sequence:
Chris@87 1677 if hasattr(element, '__iter__'):
Chris@87 1678 for f in _flatsequence(element):
Chris@87 1679 yield f
Chris@87 1680 else:
Chris@87 1681 yield element
Chris@87 1682 except TypeError:
Chris@87 1683 yield sequence
Chris@87 1684 #
Chris@87 1685 mask = np.asarray(mask)
Chris@87 1686 flattened = _flatsequence(_flatmask(mask))
Chris@87 1687 return np.array([_ for _ in flattened], dtype=bool)
Chris@87 1688
Chris@87 1689
Chris@87 1690 def _check_mask_axis(mask, axis):
Chris@87 1691 "Check whether there are masked values along the given axis"
Chris@87 1692 if mask is not nomask:
Chris@87 1693 return mask.all(axis=axis)
Chris@87 1694 return nomask
Chris@87 1695
Chris@87 1696
Chris@87 1697 #####--------------------------------------------------------------------------
Chris@87 1698 #--- --- Masking functions ---
Chris@87 1699 #####--------------------------------------------------------------------------
Chris@87 1700
Chris@87 1701 def masked_where(condition, a, copy=True):
Chris@87 1702 """
Chris@87 1703 Mask an array where a condition is met.
Chris@87 1704
Chris@87 1705 Return `a` as an array masked where `condition` is True.
Chris@87 1706 Any masked values of `a` or `condition` are also masked in the output.
Chris@87 1707
Chris@87 1708 Parameters
Chris@87 1709 ----------
Chris@87 1710 condition : array_like
Chris@87 1711 Masking condition. When `condition` tests floating point values for
Chris@87 1712 equality, consider using ``masked_values`` instead.
Chris@87 1713 a : array_like
Chris@87 1714 Array to mask.
Chris@87 1715 copy : bool
Chris@87 1716 If True (default) make a copy of `a` in the result. If False modify
Chris@87 1717 `a` in place and return a view.
Chris@87 1718
Chris@87 1719 Returns
Chris@87 1720 -------
Chris@87 1721 result : MaskedArray
Chris@87 1722 The result of masking `a` where `condition` is True.
Chris@87 1723
Chris@87 1724 See Also
Chris@87 1725 --------
Chris@87 1726 masked_values : Mask using floating point equality.
Chris@87 1727 masked_equal : Mask where equal to a given value.
Chris@87 1728 masked_not_equal : Mask where `not` equal to a given value.
Chris@87 1729 masked_less_equal : Mask where less than or equal to a given value.
Chris@87 1730 masked_greater_equal : Mask where greater than or equal to a given value.
Chris@87 1731 masked_less : Mask where less than a given value.
Chris@87 1732 masked_greater : Mask where greater than a given value.
Chris@87 1733 masked_inside : Mask inside a given interval.
Chris@87 1734 masked_outside : Mask outside a given interval.
Chris@87 1735 masked_invalid : Mask invalid values (NaNs or infs).
Chris@87 1736
Chris@87 1737 Examples
Chris@87 1738 --------
Chris@87 1739 >>> import numpy.ma as ma
Chris@87 1740 >>> a = np.arange(4)
Chris@87 1741 >>> a
Chris@87 1742 array([0, 1, 2, 3])
Chris@87 1743 >>> ma.masked_where(a <= 2, a)
Chris@87 1744 masked_array(data = [-- -- -- 3],
Chris@87 1745 mask = [ True True True False],
Chris@87 1746 fill_value=999999)
Chris@87 1747
Chris@87 1748 Mask array `b` conditional on `a`.
Chris@87 1749
Chris@87 1750 >>> b = ['a', 'b', 'c', 'd']
Chris@87 1751 >>> ma.masked_where(a == 2, b)
Chris@87 1752 masked_array(data = [a b -- d],
Chris@87 1753 mask = [False False True False],
Chris@87 1754 fill_value=N/A)
Chris@87 1755
Chris@87 1756 Effect of the `copy` argument.
Chris@87 1757
Chris@87 1758 >>> c = ma.masked_where(a <= 2, a)
Chris@87 1759 >>> c
Chris@87 1760 masked_array(data = [-- -- -- 3],
Chris@87 1761 mask = [ True True True False],
Chris@87 1762 fill_value=999999)
Chris@87 1763 >>> c[0] = 99
Chris@87 1764 >>> c
Chris@87 1765 masked_array(data = [99 -- -- 3],
Chris@87 1766 mask = [False True True False],
Chris@87 1767 fill_value=999999)
Chris@87 1768 >>> a
Chris@87 1769 array([0, 1, 2, 3])
Chris@87 1770 >>> c = ma.masked_where(a <= 2, a, copy=False)
Chris@87 1771 >>> c[0] = 99
Chris@87 1772 >>> c
Chris@87 1773 masked_array(data = [99 -- -- 3],
Chris@87 1774 mask = [False True True False],
Chris@87 1775 fill_value=999999)
Chris@87 1776 >>> a
Chris@87 1777 array([99, 1, 2, 3])
Chris@87 1778
Chris@87 1779 When `condition` or `a` contain masked values.
Chris@87 1780
Chris@87 1781 >>> a = np.arange(4)
Chris@87 1782 >>> a = ma.masked_where(a == 2, a)
Chris@87 1783 >>> a
Chris@87 1784 masked_array(data = [0 1 -- 3],
Chris@87 1785 mask = [False False True False],
Chris@87 1786 fill_value=999999)
Chris@87 1787 >>> b = np.arange(4)
Chris@87 1788 >>> b = ma.masked_where(b == 0, b)
Chris@87 1789 >>> b
Chris@87 1790 masked_array(data = [-- 1 2 3],
Chris@87 1791 mask = [ True False False False],
Chris@87 1792 fill_value=999999)
Chris@87 1793 >>> ma.masked_where(a == 3, b)
Chris@87 1794 masked_array(data = [-- 1 -- --],
Chris@87 1795 mask = [ True False True True],
Chris@87 1796 fill_value=999999)
Chris@87 1797
Chris@87 1798 """
Chris@87 1799 # Make sure that condition is a valid standard-type mask.
Chris@87 1800 cond = make_mask(condition)
Chris@87 1801 a = np.array(a, copy=copy, subok=True)
Chris@87 1802
Chris@87 1803 (cshape, ashape) = (cond.shape, a.shape)
Chris@87 1804 if cshape and cshape != ashape:
Chris@87 1805 raise IndexError("Inconsistant shape between the condition and the input"
Chris@87 1806 " (got %s and %s)" % (cshape, ashape))
Chris@87 1807 if hasattr(a, '_mask'):
Chris@87 1808 cond = mask_or(cond, a._mask)
Chris@87 1809 cls = type(a)
Chris@87 1810 else:
Chris@87 1811 cls = MaskedArray
Chris@87 1812 result = a.view(cls)
Chris@87 1813 result._mask = cond
Chris@87 1814 return result
Chris@87 1815
Chris@87 1816
Chris@87 1817 def masked_greater(x, value, copy=True):
Chris@87 1818 """
Chris@87 1819 Mask an array where greater than a given value.
Chris@87 1820
Chris@87 1821 This function is a shortcut to ``masked_where``, with
Chris@87 1822 `condition` = (x > value).
Chris@87 1823
Chris@87 1824 See Also
Chris@87 1825 --------
Chris@87 1826 masked_where : Mask where a condition is met.
Chris@87 1827
Chris@87 1828 Examples
Chris@87 1829 --------
Chris@87 1830 >>> import numpy.ma as ma
Chris@87 1831 >>> a = np.arange(4)
Chris@87 1832 >>> a
Chris@87 1833 array([0, 1, 2, 3])
Chris@87 1834 >>> ma.masked_greater(a, 2)
Chris@87 1835 masked_array(data = [0 1 2 --],
Chris@87 1836 mask = [False False False True],
Chris@87 1837 fill_value=999999)
Chris@87 1838
Chris@87 1839 """
Chris@87 1840 return masked_where(greater(x, value), x, copy=copy)
Chris@87 1841
Chris@87 1842
Chris@87 1843 def masked_greater_equal(x, value, copy=True):
Chris@87 1844 """
Chris@87 1845 Mask an array where greater than or equal to a given value.
Chris@87 1846
Chris@87 1847 This function is a shortcut to ``masked_where``, with
Chris@87 1848 `condition` = (x >= value).
Chris@87 1849
Chris@87 1850 See Also
Chris@87 1851 --------
Chris@87 1852 masked_where : Mask where a condition is met.
Chris@87 1853
Chris@87 1854 Examples
Chris@87 1855 --------
Chris@87 1856 >>> import numpy.ma as ma
Chris@87 1857 >>> a = np.arange(4)
Chris@87 1858 >>> a
Chris@87 1859 array([0, 1, 2, 3])
Chris@87 1860 >>> ma.masked_greater_equal(a, 2)
Chris@87 1861 masked_array(data = [0 1 -- --],
Chris@87 1862 mask = [False False True True],
Chris@87 1863 fill_value=999999)
Chris@87 1864
Chris@87 1865 """
Chris@87 1866 return masked_where(greater_equal(x, value), x, copy=copy)
Chris@87 1867
Chris@87 1868
Chris@87 1869 def masked_less(x, value, copy=True):
Chris@87 1870 """
Chris@87 1871 Mask an array where less than a given value.
Chris@87 1872
Chris@87 1873 This function is a shortcut to ``masked_where``, with
Chris@87 1874 `condition` = (x < value).
Chris@87 1875
Chris@87 1876 See Also
Chris@87 1877 --------
Chris@87 1878 masked_where : Mask where a condition is met.
Chris@87 1879
Chris@87 1880 Examples
Chris@87 1881 --------
Chris@87 1882 >>> import numpy.ma as ma
Chris@87 1883 >>> a = np.arange(4)
Chris@87 1884 >>> a
Chris@87 1885 array([0, 1, 2, 3])
Chris@87 1886 >>> ma.masked_less(a, 2)
Chris@87 1887 masked_array(data = [-- -- 2 3],
Chris@87 1888 mask = [ True True False False],
Chris@87 1889 fill_value=999999)
Chris@87 1890
Chris@87 1891 """
Chris@87 1892 return masked_where(less(x, value), x, copy=copy)
Chris@87 1893
Chris@87 1894
Chris@87 1895 def masked_less_equal(x, value, copy=True):
Chris@87 1896 """
Chris@87 1897 Mask an array where less than or equal to a given value.
Chris@87 1898
Chris@87 1899 This function is a shortcut to ``masked_where``, with
Chris@87 1900 `condition` = (x <= value).
Chris@87 1901
Chris@87 1902 See Also
Chris@87 1903 --------
Chris@87 1904 masked_where : Mask where a condition is met.
Chris@87 1905
Chris@87 1906 Examples
Chris@87 1907 --------
Chris@87 1908 >>> import numpy.ma as ma
Chris@87 1909 >>> a = np.arange(4)
Chris@87 1910 >>> a
Chris@87 1911 array([0, 1, 2, 3])
Chris@87 1912 >>> ma.masked_less_equal(a, 2)
Chris@87 1913 masked_array(data = [-- -- -- 3],
Chris@87 1914 mask = [ True True True False],
Chris@87 1915 fill_value=999999)
Chris@87 1916
Chris@87 1917 """
Chris@87 1918 return masked_where(less_equal(x, value), x, copy=copy)
Chris@87 1919
Chris@87 1920
Chris@87 1921 def masked_not_equal(x, value, copy=True):
Chris@87 1922 """
Chris@87 1923 Mask an array where `not` equal to a given value.
Chris@87 1924
Chris@87 1925 This function is a shortcut to ``masked_where``, with
Chris@87 1926 `condition` = (x != value).
Chris@87 1927
Chris@87 1928 See Also
Chris@87 1929 --------
Chris@87 1930 masked_where : Mask where a condition is met.
Chris@87 1931
Chris@87 1932 Examples
Chris@87 1933 --------
Chris@87 1934 >>> import numpy.ma as ma
Chris@87 1935 >>> a = np.arange(4)
Chris@87 1936 >>> a
Chris@87 1937 array([0, 1, 2, 3])
Chris@87 1938 >>> ma.masked_not_equal(a, 2)
Chris@87 1939 masked_array(data = [-- -- 2 --],
Chris@87 1940 mask = [ True True False True],
Chris@87 1941 fill_value=999999)
Chris@87 1942
Chris@87 1943 """
Chris@87 1944 return masked_where(not_equal(x, value), x, copy=copy)
Chris@87 1945
Chris@87 1946
Chris@87 1947 def masked_equal(x, value, copy=True):
Chris@87 1948 """
Chris@87 1949 Mask an array where equal to a given value.
Chris@87 1950
Chris@87 1951 This function is a shortcut to ``masked_where``, with
Chris@87 1952 `condition` = (x == value). For floating point arrays,
Chris@87 1953 consider using ``masked_values(x, value)``.
Chris@87 1954
Chris@87 1955 See Also
Chris@87 1956 --------
Chris@87 1957 masked_where : Mask where a condition is met.
Chris@87 1958 masked_values : Mask using floating point equality.
Chris@87 1959
Chris@87 1960 Examples
Chris@87 1961 --------
Chris@87 1962 >>> import numpy.ma as ma
Chris@87 1963 >>> a = np.arange(4)
Chris@87 1964 >>> a
Chris@87 1965 array([0, 1, 2, 3])
Chris@87 1966 >>> ma.masked_equal(a, 2)
Chris@87 1967 masked_array(data = [0 1 -- 3],
Chris@87 1968 mask = [False False True False],
Chris@87 1969 fill_value=999999)
Chris@87 1970
Chris@87 1971 """
Chris@87 1972 # An alternative implementation relies on filling first: probably not needed.
Chris@87 1973 # d = filled(x, 0)
Chris@87 1974 # c = umath.equal(d, value)
Chris@87 1975 # m = mask_or(c, getmask(x))
Chris@87 1976 # return array(d, mask=m, copy=copy)
Chris@87 1977 output = masked_where(equal(x, value), x, copy=copy)
Chris@87 1978 output.fill_value = value
Chris@87 1979 return output
Chris@87 1980
Chris@87 1981
Chris@87 1982 def masked_inside(x, v1, v2, copy=True):
Chris@87 1983 """
Chris@87 1984 Mask an array inside a given interval.
Chris@87 1985
Chris@87 1986 Shortcut to ``masked_where``, where `condition` is True for `x` inside
Chris@87 1987 the interval [v1,v2] (v1 <= x <= v2). The boundaries `v1` and `v2`
Chris@87 1988 can be given in either order.
Chris@87 1989
Chris@87 1990 See Also
Chris@87 1991 --------
Chris@87 1992 masked_where : Mask where a condition is met.
Chris@87 1993
Chris@87 1994 Notes
Chris@87 1995 -----
Chris@87 1996 The array `x` is prefilled with its filling value.
Chris@87 1997
Chris@87 1998 Examples
Chris@87 1999 --------
Chris@87 2000 >>> import numpy.ma as ma
Chris@87 2001 >>> x = [0.31, 1.2, 0.01, 0.2, -0.4, -1.1]
Chris@87 2002 >>> ma.masked_inside(x, -0.3, 0.3)
Chris@87 2003 masked_array(data = [0.31 1.2 -- -- -0.4 -1.1],
Chris@87 2004 mask = [False False True True False False],
Chris@87 2005 fill_value=1e+20)
Chris@87 2006
Chris@87 2007 The order of `v1` and `v2` doesn't matter.
Chris@87 2008
Chris@87 2009 >>> ma.masked_inside(x, 0.3, -0.3)
Chris@87 2010 masked_array(data = [0.31 1.2 -- -- -0.4 -1.1],
Chris@87 2011 mask = [False False True True False False],
Chris@87 2012 fill_value=1e+20)
Chris@87 2013
Chris@87 2014 """
Chris@87 2015 if v2 < v1:
Chris@87 2016 (v1, v2) = (v2, v1)
Chris@87 2017 xf = filled(x)
Chris@87 2018 condition = (xf >= v1) & (xf <= v2)
Chris@87 2019 return masked_where(condition, x, copy=copy)
Chris@87 2020
Chris@87 2021
Chris@87 2022 def masked_outside(x, v1, v2, copy=True):
Chris@87 2023 """
Chris@87 2024 Mask an array outside a given interval.
Chris@87 2025
Chris@87 2026 Shortcut to ``masked_where``, where `condition` is True for `x` outside
Chris@87 2027 the interval [v1,v2] (x < v1)|(x > v2).
Chris@87 2028 The boundaries `v1` and `v2` can be given in either order.
Chris@87 2029
Chris@87 2030 See Also
Chris@87 2031 --------
Chris@87 2032 masked_where : Mask where a condition is met.
Chris@87 2033
Chris@87 2034 Notes
Chris@87 2035 -----
Chris@87 2036 The array `x` is prefilled with its filling value.
Chris@87 2037
Chris@87 2038 Examples
Chris@87 2039 --------
Chris@87 2040 >>> import numpy.ma as ma
Chris@87 2041 >>> x = [0.31, 1.2, 0.01, 0.2, -0.4, -1.1]
Chris@87 2042 >>> ma.masked_outside(x, -0.3, 0.3)
Chris@87 2043 masked_array(data = [-- -- 0.01 0.2 -- --],
Chris@87 2044 mask = [ True True False False True True],
Chris@87 2045 fill_value=1e+20)
Chris@87 2046
Chris@87 2047 The order of `v1` and `v2` doesn't matter.
Chris@87 2048
Chris@87 2049 >>> ma.masked_outside(x, 0.3, -0.3)
Chris@87 2050 masked_array(data = [-- -- 0.01 0.2 -- --],
Chris@87 2051 mask = [ True True False False True True],
Chris@87 2052 fill_value=1e+20)
Chris@87 2053
Chris@87 2054 """
Chris@87 2055 if v2 < v1:
Chris@87 2056 (v1, v2) = (v2, v1)
Chris@87 2057 xf = filled(x)
Chris@87 2058 condition = (xf < v1) | (xf > v2)
Chris@87 2059 return masked_where(condition, x, copy=copy)
Chris@87 2060
Chris@87 2061
Chris@87 2062 def masked_object(x, value, copy=True, shrink=True):
Chris@87 2063 """
Chris@87 2064 Mask the array `x` where the data are exactly equal to value.
Chris@87 2065
Chris@87 2066 This function is similar to `masked_values`, but only suitable
Chris@87 2067 for object arrays: for floating point, use `masked_values` instead.
Chris@87 2068
Chris@87 2069 Parameters
Chris@87 2070 ----------
Chris@87 2071 x : array_like
Chris@87 2072 Array to mask
Chris@87 2073 value : object
Chris@87 2074 Comparison value
Chris@87 2075 copy : {True, False}, optional
Chris@87 2076 Whether to return a copy of `x`.
Chris@87 2077 shrink : {True, False}, optional
Chris@87 2078 Whether to collapse a mask full of False to nomask
Chris@87 2079
Chris@87 2080 Returns
Chris@87 2081 -------
Chris@87 2082 result : MaskedArray
Chris@87 2083 The result of masking `x` where equal to `value`.
Chris@87 2084
Chris@87 2085 See Also
Chris@87 2086 --------
Chris@87 2087 masked_where : Mask where a condition is met.
Chris@87 2088 masked_equal : Mask where equal to a given value (integers).
Chris@87 2089 masked_values : Mask using floating point equality.
Chris@87 2090
Chris@87 2091 Examples
Chris@87 2092 --------
Chris@87 2093 >>> import numpy.ma as ma
Chris@87 2094 >>> food = np.array(['green_eggs', 'ham'], dtype=object)
Chris@87 2095 >>> # don't eat spoiled food
Chris@87 2096 >>> eat = ma.masked_object(food, 'green_eggs')
Chris@87 2097 >>> print eat
Chris@87 2098 [-- ham]
Chris@87 2099 >>> # plain ol` ham is boring
Chris@87 2100 >>> fresh_food = np.array(['cheese', 'ham', 'pineapple'], dtype=object)
Chris@87 2101 >>> eat = ma.masked_object(fresh_food, 'green_eggs')
Chris@87 2102 >>> print eat
Chris@87 2103 [cheese ham pineapple]
Chris@87 2104
Chris@87 2105 Note that `mask` is set to ``nomask`` if possible.
Chris@87 2106
Chris@87 2107 >>> eat
Chris@87 2108 masked_array(data = [cheese ham pineapple],
Chris@87 2109 mask = False,
Chris@87 2110 fill_value=?)
Chris@87 2111
Chris@87 2112 """
Chris@87 2113 if isMaskedArray(x):
Chris@87 2114 condition = umath.equal(x._data, value)
Chris@87 2115 mask = x._mask
Chris@87 2116 else:
Chris@87 2117 condition = umath.equal(np.asarray(x), value)
Chris@87 2118 mask = nomask
Chris@87 2119 mask = mask_or(mask, make_mask(condition, shrink=shrink))
Chris@87 2120 return masked_array(x, mask=mask, copy=copy, fill_value=value)
Chris@87 2121
Chris@87 2122
Chris@87 2123 def masked_values(x, value, rtol=1e-5, atol=1e-8, copy=True, shrink=True):
Chris@87 2124 """
Chris@87 2125 Mask using floating point equality.
Chris@87 2126
Chris@87 2127 Return a MaskedArray, masked where the data in array `x` are approximately
Chris@87 2128 equal to `value`, i.e. where the following condition is True
Chris@87 2129
Chris@87 2130 (abs(x - value) <= atol+rtol*abs(value))
Chris@87 2131
Chris@87 2132 The fill_value is set to `value` and the mask is set to ``nomask`` if
Chris@87 2133 possible. For integers, consider using ``masked_equal``.
Chris@87 2134
Chris@87 2135 Parameters
Chris@87 2136 ----------
Chris@87 2137 x : array_like
Chris@87 2138 Array to mask.
Chris@87 2139 value : float
Chris@87 2140 Masking value.
Chris@87 2141 rtol : float, optional
Chris@87 2142 Tolerance parameter.
Chris@87 2143 atol : float, optional
Chris@87 2144 Tolerance parameter (1e-8).
Chris@87 2145 copy : bool, optional
Chris@87 2146 Whether to return a copy of `x`.
Chris@87 2147 shrink : bool, optional
Chris@87 2148 Whether to collapse a mask full of False to ``nomask``.
Chris@87 2149
Chris@87 2150 Returns
Chris@87 2151 -------
Chris@87 2152 result : MaskedArray
Chris@87 2153 The result of masking `x` where approximately equal to `value`.
Chris@87 2154
Chris@87 2155 See Also
Chris@87 2156 --------
Chris@87 2157 masked_where : Mask where a condition is met.
Chris@87 2158 masked_equal : Mask where equal to a given value (integers).
Chris@87 2159
Chris@87 2160 Examples
Chris@87 2161 --------
Chris@87 2162 >>> import numpy.ma as ma
Chris@87 2163 >>> x = np.array([1, 1.1, 2, 1.1, 3])
Chris@87 2164 >>> ma.masked_values(x, 1.1)
Chris@87 2165 masked_array(data = [1.0 -- 2.0 -- 3.0],
Chris@87 2166 mask = [False True False True False],
Chris@87 2167 fill_value=1.1)
Chris@87 2168
Chris@87 2169 Note that `mask` is set to ``nomask`` if possible.
Chris@87 2170
Chris@87 2171 >>> ma.masked_values(x, 1.5)
Chris@87 2172 masked_array(data = [ 1. 1.1 2. 1.1 3. ],
Chris@87 2173 mask = False,
Chris@87 2174 fill_value=1.5)
Chris@87 2175
Chris@87 2176 For integers, the fill value will be different in general to the
Chris@87 2177 result of ``masked_equal``.
Chris@87 2178
Chris@87 2179 >>> x = np.arange(5)
Chris@87 2180 >>> x
Chris@87 2181 array([0, 1, 2, 3, 4])
Chris@87 2182 >>> ma.masked_values(x, 2)
Chris@87 2183 masked_array(data = [0 1 -- 3 4],
Chris@87 2184 mask = [False False True False False],
Chris@87 2185 fill_value=2)
Chris@87 2186 >>> ma.masked_equal(x, 2)
Chris@87 2187 masked_array(data = [0 1 -- 3 4],
Chris@87 2188 mask = [False False True False False],
Chris@87 2189 fill_value=999999)
Chris@87 2190
Chris@87 2191 """
Chris@87 2192 mabs = umath.absolute
Chris@87 2193 xnew = filled(x, value)
Chris@87 2194 if issubclass(xnew.dtype.type, np.floating):
Chris@87 2195 condition = umath.less_equal(mabs(xnew - value), atol + rtol * mabs(value))
Chris@87 2196 mask = getattr(x, '_mask', nomask)
Chris@87 2197 else:
Chris@87 2198 condition = umath.equal(xnew, value)
Chris@87 2199 mask = nomask
Chris@87 2200 mask = mask_or(mask, make_mask(condition, shrink=shrink))
Chris@87 2201 return masked_array(xnew, mask=mask, copy=copy, fill_value=value)
Chris@87 2202
Chris@87 2203
Chris@87 2204 def masked_invalid(a, copy=True):
Chris@87 2205 """
Chris@87 2206 Mask an array where invalid values occur (NaNs or infs).
Chris@87 2207
Chris@87 2208 This function is a shortcut to ``masked_where``, with
Chris@87 2209 `condition` = ~(np.isfinite(a)). Any pre-existing mask is conserved.
Chris@87 2210 Only applies to arrays with a dtype where NaNs or infs make sense
Chris@87 2211 (i.e. floating point types), but accepts any array_like object.
Chris@87 2212
Chris@87 2213 See Also
Chris@87 2214 --------
Chris@87 2215 masked_where : Mask where a condition is met.
Chris@87 2216
Chris@87 2217 Examples
Chris@87 2218 --------
Chris@87 2219 >>> import numpy.ma as ma
Chris@87 2220 >>> a = np.arange(5, dtype=np.float)
Chris@87 2221 >>> a[2] = np.NaN
Chris@87 2222 >>> a[3] = np.PINF
Chris@87 2223 >>> a
Chris@87 2224 array([ 0., 1., NaN, Inf, 4.])
Chris@87 2225 >>> ma.masked_invalid(a)
Chris@87 2226 masked_array(data = [0.0 1.0 -- -- 4.0],
Chris@87 2227 mask = [False False True True False],
Chris@87 2228 fill_value=1e+20)
Chris@87 2229
Chris@87 2230 """
Chris@87 2231 a = np.array(a, copy=copy, subok=True)
Chris@87 2232 mask = getattr(a, '_mask', None)
Chris@87 2233 if mask is not None:
Chris@87 2234 condition = ~(np.isfinite(getdata(a)))
Chris@87 2235 if mask is not nomask:
Chris@87 2236 condition |= mask
Chris@87 2237 cls = type(a)
Chris@87 2238 else:
Chris@87 2239 condition = ~(np.isfinite(a))
Chris@87 2240 cls = MaskedArray
Chris@87 2241 result = a.view(cls)
Chris@87 2242 result._mask = condition
Chris@87 2243 return result
Chris@87 2244
Chris@87 2245
Chris@87 2246 #####--------------------------------------------------------------------------
Chris@87 2247 #---- --- Printing options ---
Chris@87 2248 #####--------------------------------------------------------------------------
Chris@87 2249
Chris@87 2250 class _MaskedPrintOption:
Chris@87 2251 """
Chris@87 2252 Handle the string used to represent missing data in a masked array.
Chris@87 2253
Chris@87 2254 """
Chris@87 2255 def __init__ (self, display):
Chris@87 2256 "Create the masked_print_option object."
Chris@87 2257 self._display = display
Chris@87 2258 self._enabled = True
Chris@87 2259
Chris@87 2260 def display(self):
Chris@87 2261 "Display the string to print for masked values."
Chris@87 2262 return self._display
Chris@87 2263
Chris@87 2264 def set_display (self, s):
Chris@87 2265 "Set the string to print for masked values."
Chris@87 2266 self._display = s
Chris@87 2267
Chris@87 2268 def enabled(self):
Chris@87 2269 "Is the use of the display value enabled?"
Chris@87 2270 return self._enabled
Chris@87 2271
Chris@87 2272 def enable(self, shrink=1):
Chris@87 2273 "Set the enabling shrink to `shrink`."
Chris@87 2274 self._enabled = shrink
Chris@87 2275
Chris@87 2276 def __str__ (self):
Chris@87 2277 return str(self._display)
Chris@87 2278
Chris@87 2279 __repr__ = __str__
Chris@87 2280
Chris@87 2281 #if you single index into a masked location you get this object.
Chris@87 2282 masked_print_option = _MaskedPrintOption('--')
Chris@87 2283
Chris@87 2284
Chris@87 2285 def _recursive_printoption(result, mask, printopt):
Chris@87 2286 """
Chris@87 2287 Puts printoptions in result where mask is True.
Chris@87 2288 Private function allowing for recursion
Chris@87 2289 """
Chris@87 2290 names = result.dtype.names
Chris@87 2291 for name in names:
Chris@87 2292 (curdata, curmask) = (result[name], mask[name])
Chris@87 2293 if curdata.dtype.names:
Chris@87 2294 _recursive_printoption(curdata, curmask, printopt)
Chris@87 2295 else:
Chris@87 2296 np.copyto(curdata, printopt, where=curmask)
Chris@87 2297 return
Chris@87 2298
Chris@87 2299 _print_templates = dict(long_std="""\
Chris@87 2300 masked_%(name)s(data =
Chris@87 2301 %(data)s,
Chris@87 2302 %(nlen)s mask =
Chris@87 2303 %(mask)s,
Chris@87 2304 %(nlen)s fill_value = %(fill)s)
Chris@87 2305 """,
Chris@87 2306 short_std="""\
Chris@87 2307 masked_%(name)s(data = %(data)s,
Chris@87 2308 %(nlen)s mask = %(mask)s,
Chris@87 2309 %(nlen)s fill_value = %(fill)s)
Chris@87 2310 """,
Chris@87 2311 long_flx="""\
Chris@87 2312 masked_%(name)s(data =
Chris@87 2313 %(data)s,
Chris@87 2314 %(nlen)s mask =
Chris@87 2315 %(mask)s,
Chris@87 2316 %(nlen)s fill_value = %(fill)s,
Chris@87 2317 %(nlen)s dtype = %(dtype)s)
Chris@87 2318 """,
Chris@87 2319 short_flx="""\
Chris@87 2320 masked_%(name)s(data = %(data)s,
Chris@87 2321 %(nlen)s mask = %(mask)s,
Chris@87 2322 %(nlen)s fill_value = %(fill)s,
Chris@87 2323 %(nlen)s dtype = %(dtype)s)
Chris@87 2324 """)
Chris@87 2325
Chris@87 2326 #####--------------------------------------------------------------------------
Chris@87 2327 #---- --- MaskedArray class ---
Chris@87 2328 #####--------------------------------------------------------------------------
Chris@87 2329
Chris@87 2330 def _recursive_filled(a, mask, fill_value):
Chris@87 2331 """
Chris@87 2332 Recursively fill `a` with `fill_value`.
Chris@87 2333 Private function
Chris@87 2334 """
Chris@87 2335 names = a.dtype.names
Chris@87 2336 for name in names:
Chris@87 2337 current = a[name]
Chris@87 2338 if current.dtype.names:
Chris@87 2339 _recursive_filled(current, mask[name], fill_value[name])
Chris@87 2340 else:
Chris@87 2341 np.copyto(current, fill_value[name], where=mask[name])
Chris@87 2342
Chris@87 2343
Chris@87 2344
Chris@87 2345 def flatten_structured_array(a):
Chris@87 2346 """
Chris@87 2347 Flatten a structured array.
Chris@87 2348
Chris@87 2349 The data type of the output is chosen such that it can represent all of the
Chris@87 2350 (nested) fields.
Chris@87 2351
Chris@87 2352 Parameters
Chris@87 2353 ----------
Chris@87 2354 a : structured array
Chris@87 2355
Chris@87 2356 Returns
Chris@87 2357 -------
Chris@87 2358 output : masked array or ndarray
Chris@87 2359 A flattened masked array if the input is a masked array, otherwise a
Chris@87 2360 standard ndarray.
Chris@87 2361
Chris@87 2362 Examples
Chris@87 2363 --------
Chris@87 2364 >>> ndtype = [('a', int), ('b', float)]
Chris@87 2365 >>> a = np.array([(1, 1), (2, 2)], dtype=ndtype)
Chris@87 2366 >>> flatten_structured_array(a)
Chris@87 2367 array([[1., 1.],
Chris@87 2368 [2., 2.]])
Chris@87 2369
Chris@87 2370 """
Chris@87 2371 #
Chris@87 2372 def flatten_sequence(iterable):
Chris@87 2373 """Flattens a compound of nested iterables."""
Chris@87 2374 for elm in iter(iterable):
Chris@87 2375 if hasattr(elm, '__iter__'):
Chris@87 2376 for f in flatten_sequence(elm):
Chris@87 2377 yield f
Chris@87 2378 else:
Chris@87 2379 yield elm
Chris@87 2380 #
Chris@87 2381 a = np.asanyarray(a)
Chris@87 2382 inishape = a.shape
Chris@87 2383 a = a.ravel()
Chris@87 2384 if isinstance(a, MaskedArray):
Chris@87 2385 out = np.array([tuple(flatten_sequence(d.item())) for d in a._data])
Chris@87 2386 out = out.view(MaskedArray)
Chris@87 2387 out._mask = np.array([tuple(flatten_sequence(d.item()))
Chris@87 2388 for d in getmaskarray(a)])
Chris@87 2389 else:
Chris@87 2390 out = np.array([tuple(flatten_sequence(d.item())) for d in a])
Chris@87 2391 if len(inishape) > 1:
Chris@87 2392 newshape = list(out.shape)
Chris@87 2393 newshape[0] = inishape
Chris@87 2394 out.shape = tuple(flatten_sequence(newshape))
Chris@87 2395 return out
Chris@87 2396
Chris@87 2397
Chris@87 2398
Chris@87 2399 class _arraymethod(object):
Chris@87 2400 """
Chris@87 2401 Define a wrapper for basic array methods.
Chris@87 2402
Chris@87 2403 Upon call, returns a masked array, where the new ``_data`` array is
Chris@87 2404 the output of the corresponding method called on the original
Chris@87 2405 ``_data``.
Chris@87 2406
Chris@87 2407 If `onmask` is True, the new mask is the output of the method called
Chris@87 2408 on the initial mask. Otherwise, the new mask is just a reference
Chris@87 2409 to the initial mask.
Chris@87 2410
Chris@87 2411 Attributes
Chris@87 2412 ----------
Chris@87 2413 _onmask : bool
Chris@87 2414 Holds the `onmask` parameter.
Chris@87 2415 obj : object
Chris@87 2416 The object calling `_arraymethod`.
Chris@87 2417
Chris@87 2418 Parameters
Chris@87 2419 ----------
Chris@87 2420 funcname : str
Chris@87 2421 Name of the function to apply on data.
Chris@87 2422 onmask : bool
Chris@87 2423 Whether the mask must be processed also (True) or left
Chris@87 2424 alone (False). Default is True. Make available as `_onmask`
Chris@87 2425 attribute.
Chris@87 2426
Chris@87 2427 """
Chris@87 2428 def __init__(self, funcname, onmask=True):
Chris@87 2429 self.__name__ = funcname
Chris@87 2430 self._onmask = onmask
Chris@87 2431 self.obj = None
Chris@87 2432 self.__doc__ = self.getdoc()
Chris@87 2433 #
Chris@87 2434 def getdoc(self):
Chris@87 2435 "Return the doc of the function (from the doc of the method)."
Chris@87 2436 methdoc = getattr(ndarray, self.__name__, None) or \
Chris@87 2437 getattr(np, self.__name__, None)
Chris@87 2438 if methdoc is not None:
Chris@87 2439 return methdoc.__doc__
Chris@87 2440 #
Chris@87 2441 def __get__(self, obj, objtype=None):
Chris@87 2442 self.obj = obj
Chris@87 2443 return self
Chris@87 2444 #
Chris@87 2445 def __call__(self, *args, **params):
Chris@87 2446 methodname = self.__name__
Chris@87 2447 instance = self.obj
Chris@87 2448 # Fallback : if the instance has not been initialized, use the first arg
Chris@87 2449 if instance is None:
Chris@87 2450 args = list(args)
Chris@87 2451 instance = args.pop(0)
Chris@87 2452 data = instance._data
Chris@87 2453 mask = instance._mask
Chris@87 2454 cls = type(instance)
Chris@87 2455 result = getattr(data, methodname)(*args, **params).view(cls)
Chris@87 2456 result._update_from(instance)
Chris@87 2457 if result.ndim:
Chris@87 2458 if not self._onmask:
Chris@87 2459 result.__setmask__(mask)
Chris@87 2460 elif mask is not nomask:
Chris@87 2461 result.__setmask__(getattr(mask, methodname)(*args, **params))
Chris@87 2462 else:
Chris@87 2463 if mask.ndim and (not mask.dtype.names and mask.all()):
Chris@87 2464 return masked
Chris@87 2465 return result
Chris@87 2466
Chris@87 2467
Chris@87 2468 class MaskedIterator(object):
Chris@87 2469 """
Chris@87 2470 Flat iterator object to iterate over masked arrays.
Chris@87 2471
Chris@87 2472 A `MaskedIterator` iterator is returned by ``x.flat`` for any masked array
Chris@87 2473 `x`. It allows iterating over the array as if it were a 1-D array,
Chris@87 2474 either in a for-loop or by calling its `next` method.
Chris@87 2475
Chris@87 2476 Iteration is done in C-contiguous style, with the last index varying the
Chris@87 2477 fastest. The iterator can also be indexed using basic slicing or
Chris@87 2478 advanced indexing.
Chris@87 2479
Chris@87 2480 See Also
Chris@87 2481 --------
Chris@87 2482 MaskedArray.flat : Return a flat iterator over an array.
Chris@87 2483 MaskedArray.flatten : Returns a flattened copy of an array.
Chris@87 2484
Chris@87 2485 Notes
Chris@87 2486 -----
Chris@87 2487 `MaskedIterator` is not exported by the `ma` module. Instead of
Chris@87 2488 instantiating a `MaskedIterator` directly, use `MaskedArray.flat`.
Chris@87 2489
Chris@87 2490 Examples
Chris@87 2491 --------
Chris@87 2492 >>> x = np.ma.array(arange(6).reshape(2, 3))
Chris@87 2493 >>> fl = x.flat
Chris@87 2494 >>> type(fl)
Chris@87 2495 <class 'numpy.ma.core.MaskedIterator'>
Chris@87 2496 >>> for item in fl:
Chris@87 2497 ... print item
Chris@87 2498 ...
Chris@87 2499 0
Chris@87 2500 1
Chris@87 2501 2
Chris@87 2502 3
Chris@87 2503 4
Chris@87 2504 5
Chris@87 2505
Chris@87 2506 Extracting more than a single element b indexing the `MaskedIterator`
Chris@87 2507 returns a masked array:
Chris@87 2508
Chris@87 2509 >>> fl[2:4]
Chris@87 2510 masked_array(data = [2 3],
Chris@87 2511 mask = False,
Chris@87 2512 fill_value = 999999)
Chris@87 2513
Chris@87 2514 """
Chris@87 2515 def __init__(self, ma):
Chris@87 2516 self.ma = ma
Chris@87 2517 self.dataiter = ma._data.flat
Chris@87 2518 #
Chris@87 2519 if ma._mask is nomask:
Chris@87 2520 self.maskiter = None
Chris@87 2521 else:
Chris@87 2522 self.maskiter = ma._mask.flat
Chris@87 2523
Chris@87 2524 def __iter__(self):
Chris@87 2525 return self
Chris@87 2526
Chris@87 2527 def __getitem__(self, indx):
Chris@87 2528 result = self.dataiter.__getitem__(indx).view(type(self.ma))
Chris@87 2529 if self.maskiter is not None:
Chris@87 2530 _mask = self.maskiter.__getitem__(indx)
Chris@87 2531 if isinstance(_mask, ndarray):
Chris@87 2532 # set shape to match that of data; this is needed for matrices
Chris@87 2533 _mask.shape = result.shape
Chris@87 2534 result._mask = _mask
Chris@87 2535 elif isinstance(_mask, np.void):
Chris@87 2536 return mvoid(result, mask=_mask, hardmask=self.ma._hardmask)
Chris@87 2537 elif _mask: # Just a scalar, masked
Chris@87 2538 return masked
Chris@87 2539 return result
Chris@87 2540
Chris@87 2541 ### This won't work is ravel makes a copy
Chris@87 2542 def __setitem__(self, index, value):
Chris@87 2543 self.dataiter[index] = getdata(value)
Chris@87 2544 if self.maskiter is not None:
Chris@87 2545 self.maskiter[index] = getmaskarray(value)
Chris@87 2546
Chris@87 2547 def __next__(self):
Chris@87 2548 """
Chris@87 2549 Return the next value, or raise StopIteration.
Chris@87 2550
Chris@87 2551 Examples
Chris@87 2552 --------
Chris@87 2553 >>> x = np.ma.array([3, 2], mask=[0, 1])
Chris@87 2554 >>> fl = x.flat
Chris@87 2555 >>> fl.next()
Chris@87 2556 3
Chris@87 2557 >>> fl.next()
Chris@87 2558 masked_array(data = --,
Chris@87 2559 mask = True,
Chris@87 2560 fill_value = 1e+20)
Chris@87 2561 >>> fl.next()
Chris@87 2562 Traceback (most recent call last):
Chris@87 2563 File "<stdin>", line 1, in <module>
Chris@87 2564 File "/home/ralf/python/numpy/numpy/ma/core.py", line 2243, in next
Chris@87 2565 d = self.dataiter.next()
Chris@87 2566 StopIteration
Chris@87 2567
Chris@87 2568 """
Chris@87 2569 d = next(self.dataiter)
Chris@87 2570 if self.maskiter is not None:
Chris@87 2571 m = next(self.maskiter)
Chris@87 2572 if isinstance(m, np.void):
Chris@87 2573 return mvoid(d, mask=m, hardmask=self.ma._hardmask)
Chris@87 2574 elif m: # Just a scalar, masked
Chris@87 2575 return masked
Chris@87 2576 return d
Chris@87 2577
Chris@87 2578 next = __next__
Chris@87 2579
Chris@87 2580
Chris@87 2581 class MaskedArray(ndarray):
Chris@87 2582 """
Chris@87 2583 An array class with possibly masked values.
Chris@87 2584
Chris@87 2585 Masked values of True exclude the corresponding element from any
Chris@87 2586 computation.
Chris@87 2587
Chris@87 2588 Construction::
Chris@87 2589
Chris@87 2590 x = MaskedArray(data, mask=nomask, dtype=None,
Chris@87 2591 copy=False, subok=True, ndmin=0, fill_value=None,
Chris@87 2592 keep_mask=True, hard_mask=None, shrink=True)
Chris@87 2593
Chris@87 2594 Parameters
Chris@87 2595 ----------
Chris@87 2596 data : array_like
Chris@87 2597 Input data.
Chris@87 2598 mask : sequence, optional
Chris@87 2599 Mask. Must be convertible to an array of booleans with the same
Chris@87 2600 shape as `data`. True indicates a masked (i.e. invalid) data.
Chris@87 2601 dtype : dtype, optional
Chris@87 2602 Data type of the output.
Chris@87 2603 If `dtype` is None, the type of the data argument (``data.dtype``)
Chris@87 2604 is used. If `dtype` is not None and different from ``data.dtype``,
Chris@87 2605 a copy is performed.
Chris@87 2606 copy : bool, optional
Chris@87 2607 Whether to copy the input data (True), or to use a reference instead.
Chris@87 2608 Default is False.
Chris@87 2609 subok : bool, optional
Chris@87 2610 Whether to return a subclass of `MaskedArray` if possible (True) or a
Chris@87 2611 plain `MaskedArray`. Default is True.
Chris@87 2612 ndmin : int, optional
Chris@87 2613 Minimum number of dimensions. Default is 0.
Chris@87 2614 fill_value : scalar, optional
Chris@87 2615 Value used to fill in the masked values when necessary.
Chris@87 2616 If None, a default based on the data-type is used.
Chris@87 2617 keep_mask : bool, optional
Chris@87 2618 Whether to combine `mask` with the mask of the input data, if any
Chris@87 2619 (True), or to use only `mask` for the output (False). Default is True.
Chris@87 2620 hard_mask : bool, optional
Chris@87 2621 Whether to use a hard mask or not. With a hard mask, masked values
Chris@87 2622 cannot be unmasked. Default is False.
Chris@87 2623 shrink : bool, optional
Chris@87 2624 Whether to force compression of an empty mask. Default is True.
Chris@87 2625
Chris@87 2626 """
Chris@87 2627
Chris@87 2628 __array_priority__ = 15
Chris@87 2629 _defaultmask = nomask
Chris@87 2630 _defaulthardmask = False
Chris@87 2631 _baseclass = ndarray
Chris@87 2632
Chris@87 2633 def __new__(cls, data=None, mask=nomask, dtype=None, copy=False,
Chris@87 2634 subok=True, ndmin=0, fill_value=None,
Chris@87 2635 keep_mask=True, hard_mask=None, shrink=True,
Chris@87 2636 **options):
Chris@87 2637 """
Chris@87 2638 Create a new masked array from scratch.
Chris@87 2639
Chris@87 2640 Notes
Chris@87 2641 -----
Chris@87 2642 A masked array can also be created by taking a .view(MaskedArray).
Chris@87 2643
Chris@87 2644 """
Chris@87 2645 # Process data............
Chris@87 2646 _data = np.array(data, dtype=dtype, copy=copy, subok=True, ndmin=ndmin)
Chris@87 2647 _baseclass = getattr(data, '_baseclass', type(_data))
Chris@87 2648 # Check that we're not erasing the mask..........
Chris@87 2649 if isinstance(data, MaskedArray) and (data.shape != _data.shape):
Chris@87 2650 copy = True
Chris@87 2651 # Careful, cls might not always be MaskedArray...
Chris@87 2652 if not isinstance(data, cls) or not subok:
Chris@87 2653 _data = ndarray.view(_data, cls)
Chris@87 2654 else:
Chris@87 2655 _data = ndarray.view(_data, type(data))
Chris@87 2656 # Backwards compatibility w/ numpy.core.ma .......
Chris@87 2657 if hasattr(data, '_mask') and not isinstance(data, ndarray):
Chris@87 2658 _data._mask = data._mask
Chris@87 2659 _sharedmask = True
Chris@87 2660 # Process mask ...............................
Chris@87 2661 # Number of named fields (or zero if none)
Chris@87 2662 names_ = _data.dtype.names or ()
Chris@87 2663 # Type of the mask
Chris@87 2664 if names_:
Chris@87 2665 mdtype = make_mask_descr(_data.dtype)
Chris@87 2666 else:
Chris@87 2667 mdtype = MaskType
Chris@87 2668 # Case 1. : no mask in input ............
Chris@87 2669 if mask is nomask:
Chris@87 2670 # Erase the current mask ?
Chris@87 2671 if not keep_mask:
Chris@87 2672 # With a reduced version
Chris@87 2673 if shrink:
Chris@87 2674 _data._mask = nomask
Chris@87 2675 # With full version
Chris@87 2676 else:
Chris@87 2677 _data._mask = np.zeros(_data.shape, dtype=mdtype)
Chris@87 2678 # Check whether we missed something
Chris@87 2679 elif isinstance(data, (tuple, list)):
Chris@87 2680 try:
Chris@87 2681 # If data is a sequence of masked array
Chris@87 2682 mask = np.array([getmaskarray(m) for m in data],
Chris@87 2683 dtype=mdtype)
Chris@87 2684 except ValueError:
Chris@87 2685 # If data is nested
Chris@87 2686 mask = nomask
Chris@87 2687 # Force shrinking of the mask if needed (and possible)
Chris@87 2688 if (mdtype == MaskType) and mask.any():
Chris@87 2689 _data._mask = mask
Chris@87 2690 _data._sharedmask = False
Chris@87 2691 else:
Chris@87 2692 if copy:
Chris@87 2693 _data._mask = _data._mask.copy()
Chris@87 2694 _data._sharedmask = False
Chris@87 2695 # Reset the shape of the original mask
Chris@87 2696 if getmask(data) is not nomask:
Chris@87 2697 data._mask.shape = data.shape
Chris@87 2698 else:
Chris@87 2699 _data._sharedmask = True
Chris@87 2700 # Case 2. : With a mask in input ........
Chris@87 2701 else:
Chris@87 2702 # Read the mask with the current mdtype
Chris@87 2703 try:
Chris@87 2704 mask = np.array(mask, copy=copy, dtype=mdtype)
Chris@87 2705 # Or assume it's a sequence of bool/int
Chris@87 2706 except TypeError:
Chris@87 2707 mask = np.array([tuple([m] * len(mdtype)) for m in mask],
Chris@87 2708 dtype=mdtype)
Chris@87 2709 # Make sure the mask and the data have the same shape
Chris@87 2710 if mask.shape != _data.shape:
Chris@87 2711 (nd, nm) = (_data.size, mask.size)
Chris@87 2712 if nm == 1:
Chris@87 2713 mask = np.resize(mask, _data.shape)
Chris@87 2714 elif nm == nd:
Chris@87 2715 mask = np.reshape(mask, _data.shape)
Chris@87 2716 else:
Chris@87 2717 msg = "Mask and data not compatible: data size is %i, " + \
Chris@87 2718 "mask size is %i."
Chris@87 2719 raise MaskError(msg % (nd, nm))
Chris@87 2720 copy = True
Chris@87 2721 # Set the mask to the new value
Chris@87 2722 if _data._mask is nomask:
Chris@87 2723 _data._mask = mask
Chris@87 2724 _data._sharedmask = not copy
Chris@87 2725 else:
Chris@87 2726 if not keep_mask:
Chris@87 2727 _data._mask = mask
Chris@87 2728 _data._sharedmask = not copy
Chris@87 2729 else:
Chris@87 2730 if names_:
Chris@87 2731 def _recursive_or(a, b):
Chris@87 2732 "do a|=b on each field of a, recursively"
Chris@87 2733 for name in a.dtype.names:
Chris@87 2734 (af, bf) = (a[name], b[name])
Chris@87 2735 if af.dtype.names:
Chris@87 2736 _recursive_or(af, bf)
Chris@87 2737 else:
Chris@87 2738 af |= bf
Chris@87 2739 return
Chris@87 2740 _recursive_or(_data._mask, mask)
Chris@87 2741 else:
Chris@87 2742 _data._mask = np.logical_or(mask, _data._mask)
Chris@87 2743 _data._sharedmask = False
Chris@87 2744 # Update fill_value.......
Chris@87 2745 if fill_value is None:
Chris@87 2746 fill_value = getattr(data, '_fill_value', None)
Chris@87 2747 # But don't run the check unless we have something to check....
Chris@87 2748 if fill_value is not None:
Chris@87 2749 _data._fill_value = _check_fill_value(fill_value, _data.dtype)
Chris@87 2750 # Process extra options ..
Chris@87 2751 if hard_mask is None:
Chris@87 2752 _data._hardmask = getattr(data, '_hardmask', False)
Chris@87 2753 else:
Chris@87 2754 _data._hardmask = hard_mask
Chris@87 2755 _data._baseclass = _baseclass
Chris@87 2756 return _data
Chris@87 2757 #
Chris@87 2758 def _update_from(self, obj):
Chris@87 2759 """Copies some attributes of obj to self.
Chris@87 2760 """
Chris@87 2761 if obj is not None and isinstance(obj, ndarray):
Chris@87 2762 _baseclass = type(obj)
Chris@87 2763 else:
Chris@87 2764 _baseclass = ndarray
Chris@87 2765 # We need to copy the _basedict to avoid backward propagation
Chris@87 2766 _optinfo = {}
Chris@87 2767 _optinfo.update(getattr(obj, '_optinfo', {}))
Chris@87 2768 _optinfo.update(getattr(obj, '_basedict', {}))
Chris@87 2769 if not isinstance(obj, MaskedArray):
Chris@87 2770 _optinfo.update(getattr(obj, '__dict__', {}))
Chris@87 2771 _dict = dict(_fill_value=getattr(obj, '_fill_value', None),
Chris@87 2772 _hardmask=getattr(obj, '_hardmask', False),
Chris@87 2773 _sharedmask=getattr(obj, '_sharedmask', False),
Chris@87 2774 _isfield=getattr(obj, '_isfield', False),
Chris@87 2775 _baseclass=getattr(obj, '_baseclass', _baseclass),
Chris@87 2776 _optinfo=_optinfo,
Chris@87 2777 _basedict=_optinfo)
Chris@87 2778 self.__dict__.update(_dict)
Chris@87 2779 self.__dict__.update(_optinfo)
Chris@87 2780 return
Chris@87 2781
Chris@87 2782
Chris@87 2783 def __array_finalize__(self, obj):
Chris@87 2784 """Finalizes the masked array.
Chris@87 2785 """
Chris@87 2786 # Get main attributes .........
Chris@87 2787 self._update_from(obj)
Chris@87 2788 # We have to decide how to initialize self.mask, based on
Chris@87 2789 # obj.mask. This is very difficult. There might be some
Chris@87 2790 # correspondence between the elements in the array we are being
Chris@87 2791 # created from (= obj) and us. Or... there might not. This method can
Chris@87 2792 # be called in all kinds of places for all kinds of reasons -- could
Chris@87 2793 # be empty_like, could be slicing, could be a ufunc, could be a view,
Chris@87 2794 # ... The numpy subclassing interface simply doesn't give us any way
Chris@87 2795 # to know, which means that at best this method will be based on
Chris@87 2796 # guesswork and heuristics. To make things worse, there isn't even any
Chris@87 2797 # clear consensus about what the desired behavior is. For instance,
Chris@87 2798 # most users think that np.empty_like(marr) -- which goes via this
Chris@87 2799 # method -- should return a masked array with an empty mask (see
Chris@87 2800 # gh-3404 and linked discussions), but others disagree, and they have
Chris@87 2801 # existing code which depends on empty_like returning an array that
Chris@87 2802 # matches the input mask.
Chris@87 2803 #
Chris@87 2804 # Historically our algorithm was: if the template object mask had the
Chris@87 2805 # same *number of elements* as us, then we used *it's mask object
Chris@87 2806 # itself* as our mask, so that writes to us would also write to the
Chris@87 2807 # original array. This is horribly broken in multiple ways.
Chris@87 2808 #
Chris@87 2809 # Now what we do instead is, if the template object mask has the same
Chris@87 2810 # number of elements as us, and we do not have the same base pointer
Chris@87 2811 # as the template object (b/c views like arr[...] should keep the same
Chris@87 2812 # mask), then we make a copy of the template object mask and use
Chris@87 2813 # that. This is also horribly broken but somewhat less so. Maybe.
Chris@87 2814 if isinstance(obj, ndarray):
Chris@87 2815 # XX: This looks like a bug -- shouldn't it check self.dtype
Chris@87 2816 # instead?
Chris@87 2817 if obj.dtype.names:
Chris@87 2818 _mask = getattr(obj, '_mask',
Chris@87 2819 make_mask_none(obj.shape, obj.dtype))
Chris@87 2820 else:
Chris@87 2821 _mask = getattr(obj, '_mask', nomask)
Chris@87 2822 # If self and obj point to exactly the same data, then probably
Chris@87 2823 # self is a simple view of obj (e.g., self = obj[...]), so they
Chris@87 2824 # should share the same mask. (This isn't 100% reliable, e.g. self
Chris@87 2825 # could be the first row of obj, or have strange strides, but as a
Chris@87 2826 # heuristic it's not bad.) In all other cases, we make a copy of
Chris@87 2827 # the mask, so that future modifications to 'self' do not end up
Chris@87 2828 # side-effecting 'obj' as well.
Chris@87 2829 if (obj.__array_interface__["data"][0]
Chris@87 2830 != self.__array_interface__["data"][0]):
Chris@87 2831 _mask = _mask.copy()
Chris@87 2832 else:
Chris@87 2833 _mask = nomask
Chris@87 2834 self._mask = _mask
Chris@87 2835 # Finalize the mask ...........
Chris@87 2836 if self._mask is not nomask:
Chris@87 2837 try:
Chris@87 2838 self._mask.shape = self.shape
Chris@87 2839 except ValueError:
Chris@87 2840 self._mask = nomask
Chris@87 2841 except (TypeError, AttributeError):
Chris@87 2842 # When _mask.shape is not writable (because it's a void)
Chris@87 2843 pass
Chris@87 2844 # Finalize the fill_value for structured arrays
Chris@87 2845 if self.dtype.names:
Chris@87 2846 if self._fill_value is None:
Chris@87 2847 self._fill_value = _check_fill_value(None, self.dtype)
Chris@87 2848 return
Chris@87 2849
Chris@87 2850
Chris@87 2851 def __array_wrap__(self, obj, context=None):
Chris@87 2852 """
Chris@87 2853 Special hook for ufuncs.
Chris@87 2854 Wraps the numpy array and sets the mask according to context.
Chris@87 2855 """
Chris@87 2856 result = obj.view(type(self))
Chris@87 2857 result._update_from(self)
Chris@87 2858 #..........
Chris@87 2859 if context is not None:
Chris@87 2860 result._mask = result._mask.copy()
Chris@87 2861 (func, args, _) = context
Chris@87 2862 m = reduce(mask_or, [getmaskarray(arg) for arg in args])
Chris@87 2863 # Get the domain mask................
Chris@87 2864 domain = ufunc_domain.get(func, None)
Chris@87 2865 if domain is not None:
Chris@87 2866 # Take the domain, and make sure it's a ndarray
Chris@87 2867 if len(args) > 2:
Chris@87 2868 d = filled(reduce(domain, args), True)
Chris@87 2869 else:
Chris@87 2870 d = filled(domain(*args), True)
Chris@87 2871 # Fill the result where the domain is wrong
Chris@87 2872 try:
Chris@87 2873 # Binary domain: take the last value
Chris@87 2874 fill_value = ufunc_fills[func][-1]
Chris@87 2875 except TypeError:
Chris@87 2876 # Unary domain: just use this one
Chris@87 2877 fill_value = ufunc_fills[func]
Chris@87 2878 except KeyError:
Chris@87 2879 # Domain not recognized, use fill_value instead
Chris@87 2880 fill_value = self.fill_value
Chris@87 2881 result = result.copy()
Chris@87 2882 np.copyto(result, fill_value, where=d)
Chris@87 2883 # Update the mask
Chris@87 2884 if m is nomask:
Chris@87 2885 if d is not nomask:
Chris@87 2886 m = d
Chris@87 2887 else:
Chris@87 2888 # Don't modify inplace, we risk back-propagation
Chris@87 2889 m = (m | d)
Chris@87 2890 # Make sure the mask has the proper size
Chris@87 2891 if result.shape == () and m:
Chris@87 2892 return masked
Chris@87 2893 else:
Chris@87 2894 result._mask = m
Chris@87 2895 result._sharedmask = False
Chris@87 2896 #....
Chris@87 2897 return result
Chris@87 2898
Chris@87 2899
Chris@87 2900 def view(self, dtype=None, type=None, fill_value=None):
Chris@87 2901 """
Chris@87 2902 Return a view of the MaskedArray data
Chris@87 2903
Chris@87 2904 Parameters
Chris@87 2905 ----------
Chris@87 2906 dtype : data-type or ndarray sub-class, optional
Chris@87 2907 Data-type descriptor of the returned view, e.g., float32 or int16.
Chris@87 2908 The default, None, results in the view having the same data-type
Chris@87 2909 as `a`. As with ``ndarray.view``, dtype can also be specified as
Chris@87 2910 an ndarray sub-class, which then specifies the type of the
Chris@87 2911 returned object (this is equivalent to setting the ``type``
Chris@87 2912 parameter).
Chris@87 2913 type : Python type, optional
Chris@87 2914 Type of the returned view, e.g., ndarray or matrix. Again, the
Chris@87 2915 default None results in type preservation.
Chris@87 2916
Chris@87 2917 Notes
Chris@87 2918 -----
Chris@87 2919
Chris@87 2920 ``a.view()`` is used two different ways:
Chris@87 2921
Chris@87 2922 ``a.view(some_dtype)`` or ``a.view(dtype=some_dtype)`` constructs a view
Chris@87 2923 of the array's memory with a different data-type. This can cause a
Chris@87 2924 reinterpretation of the bytes of memory.
Chris@87 2925
Chris@87 2926 ``a.view(ndarray_subclass)`` or ``a.view(type=ndarray_subclass)`` just
Chris@87 2927 returns an instance of `ndarray_subclass` that looks at the same array
Chris@87 2928 (same shape, dtype, etc.) This does not cause a reinterpretation of the
Chris@87 2929 memory.
Chris@87 2930
Chris@87 2931 If `fill_value` is not specified, but `dtype` is specified (and is not
Chris@87 2932 an ndarray sub-class), the `fill_value` of the MaskedArray will be
Chris@87 2933 reset. If neither `fill_value` nor `dtype` are specified (or if
Chris@87 2934 `dtype` is an ndarray sub-class), then the fill value is preserved.
Chris@87 2935 Finally, if `fill_value` is specified, but `dtype` is not, the fill
Chris@87 2936 value is set to the specified value.
Chris@87 2937
Chris@87 2938 For ``a.view(some_dtype)``, if ``some_dtype`` has a different number of
Chris@87 2939 bytes per entry than the previous dtype (for example, converting a
Chris@87 2940 regular array to a structured array), then the behavior of the view
Chris@87 2941 cannot be predicted just from the superficial appearance of ``a`` (shown
Chris@87 2942 by ``print(a)``). It also depends on exactly how ``a`` is stored in
Chris@87 2943 memory. Therefore if ``a`` is C-ordered versus fortran-ordered, versus
Chris@87 2944 defined as a slice or transpose, etc., the view may give different
Chris@87 2945 results.
Chris@87 2946 """
Chris@87 2947
Chris@87 2948 if dtype is None:
Chris@87 2949 if type is None:
Chris@87 2950 output = ndarray.view(self)
Chris@87 2951 else:
Chris@87 2952 output = ndarray.view(self, type)
Chris@87 2953 elif type is None:
Chris@87 2954 try:
Chris@87 2955 if issubclass(dtype, ndarray):
Chris@87 2956 output = ndarray.view(self, dtype)
Chris@87 2957 dtype = None
Chris@87 2958 else:
Chris@87 2959 output = ndarray.view(self, dtype)
Chris@87 2960 except TypeError:
Chris@87 2961 output = ndarray.view(self, dtype)
Chris@87 2962 else:
Chris@87 2963 output = ndarray.view(self, dtype, type)
Chris@87 2964 # Should we update the mask ?
Chris@87 2965 if (getattr(output, '_mask', nomask) is not nomask):
Chris@87 2966 if dtype is None:
Chris@87 2967 dtype = output.dtype
Chris@87 2968 mdtype = make_mask_descr(dtype)
Chris@87 2969 output._mask = self._mask.view(mdtype, ndarray)
Chris@87 2970 # Try to reset the shape of the mask (if we don't have a void)
Chris@87 2971 try:
Chris@87 2972 output._mask.shape = output.shape
Chris@87 2973 except (AttributeError, TypeError):
Chris@87 2974 pass
Chris@87 2975 # Make sure to reset the _fill_value if needed
Chris@87 2976 if getattr(output, '_fill_value', None) is not None:
Chris@87 2977 if fill_value is None:
Chris@87 2978 if dtype is None:
Chris@87 2979 pass # leave _fill_value as is
Chris@87 2980 else:
Chris@87 2981 output._fill_value = None
Chris@87 2982 else:
Chris@87 2983 output.fill_value = fill_value
Chris@87 2984 return output
Chris@87 2985 view.__doc__ = ndarray.view.__doc__
Chris@87 2986
Chris@87 2987
Chris@87 2988 def astype(self, newtype):
Chris@87 2989 """
Chris@87 2990 Returns a copy of the MaskedArray cast to given newtype.
Chris@87 2991
Chris@87 2992 Returns
Chris@87 2993 -------
Chris@87 2994 output : MaskedArray
Chris@87 2995 A copy of self cast to input newtype.
Chris@87 2996 The returned record shape matches self.shape.
Chris@87 2997
Chris@87 2998 Examples
Chris@87 2999 --------
Chris@87 3000 >>> x = np.ma.array([[1,2,3.1],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
Chris@87 3001 >>> print x
Chris@87 3002 [[1.0 -- 3.1]
Chris@87 3003 [-- 5.0 --]
Chris@87 3004 [7.0 -- 9.0]]
Chris@87 3005 >>> print x.astype(int32)
Chris@87 3006 [[1 -- 3]
Chris@87 3007 [-- 5 --]
Chris@87 3008 [7 -- 9]]
Chris@87 3009
Chris@87 3010 """
Chris@87 3011 newtype = np.dtype(newtype)
Chris@87 3012 output = self._data.astype(newtype).view(type(self))
Chris@87 3013 output._update_from(self)
Chris@87 3014 names = output.dtype.names
Chris@87 3015 if names is None:
Chris@87 3016 output._mask = self._mask.astype(bool)
Chris@87 3017 else:
Chris@87 3018 if self._mask is nomask:
Chris@87 3019 output._mask = nomask
Chris@87 3020 else:
Chris@87 3021 output._mask = self._mask.astype([(n, bool) for n in names])
Chris@87 3022 # Don't check _fill_value if it's None, that'll speed things up
Chris@87 3023 if self._fill_value is not None:
Chris@87 3024 output._fill_value = _check_fill_value(self._fill_value, newtype)
Chris@87 3025 return output
Chris@87 3026
Chris@87 3027
Chris@87 3028 def __getitem__(self, indx):
Chris@87 3029 """x.__getitem__(y) <==> x[y]
Chris@87 3030
Chris@87 3031 Return the item described by i, as a masked array.
Chris@87 3032
Chris@87 3033 """
Chris@87 3034 # This test is useful, but we should keep things light...
Chris@87 3035 # if getmask(indx) is not nomask:
Chris@87 3036 # msg = "Masked arrays must be filled before they can be used as indices!"
Chris@87 3037 # raise IndexError(msg)
Chris@87 3038 _data = ndarray.view(self, ndarray)
Chris@87 3039 dout = ndarray.__getitem__(_data, indx)
Chris@87 3040 # We could directly use ndarray.__getitem__ on self...
Chris@87 3041 # But then we would have to modify __array_finalize__ to prevent the
Chris@87 3042 # mask of being reshaped if it hasn't been set up properly yet...
Chris@87 3043 # So it's easier to stick to the current version
Chris@87 3044 _mask = self._mask
Chris@87 3045 if not getattr(dout, 'ndim', False):
Chris@87 3046 # A record ................
Chris@87 3047 if isinstance(dout, np.void):
Chris@87 3048 mask = _mask[indx]
Chris@87 3049 # We should always re-cast to mvoid, otherwise users can
Chris@87 3050 # change masks on rows that already have masked values, but not
Chris@87 3051 # on rows that have no masked values, which is inconsistent.
Chris@87 3052 dout = mvoid(dout, mask=mask, hardmask=self._hardmask)
Chris@87 3053 # Just a scalar............
Chris@87 3054 elif _mask is not nomask and _mask[indx]:
Chris@87 3055 return masked
Chris@87 3056 else:
Chris@87 3057 # Force dout to MA ........
Chris@87 3058 dout = dout.view(type(self))
Chris@87 3059 # Inherit attributes from self
Chris@87 3060 dout._update_from(self)
Chris@87 3061 # Check the fill_value ....
Chris@87 3062 if isinstance(indx, basestring):
Chris@87 3063 if self._fill_value is not None:
Chris@87 3064 dout._fill_value = self._fill_value[indx]
Chris@87 3065 dout._isfield = True
Chris@87 3066 # Update the mask if needed
Chris@87 3067 if _mask is not nomask:
Chris@87 3068 dout._mask = _mask[indx]
Chris@87 3069 dout._sharedmask = True
Chris@87 3070 # Note: Don't try to check for m.any(), that'll take too long...
Chris@87 3071 return dout
Chris@87 3072
Chris@87 3073 def __setitem__(self, indx, value):
Chris@87 3074 """x.__setitem__(i, y) <==> x[i]=y
Chris@87 3075
Chris@87 3076 Set item described by index. If value is masked, masks those
Chris@87 3077 locations.
Chris@87 3078
Chris@87 3079 """
Chris@87 3080 if self is masked:
Chris@87 3081 raise MaskError('Cannot alter the masked element.')
Chris@87 3082 # This test is useful, but we should keep things light...
Chris@87 3083 # if getmask(indx) is not nomask:
Chris@87 3084 # msg = "Masked arrays must be filled before they can be used as indices!"
Chris@87 3085 # raise IndexError(msg)
Chris@87 3086 _data = ndarray.view(self, ndarray.__getattribute__(self, '_baseclass'))
Chris@87 3087 _mask = ndarray.__getattribute__(self, '_mask')
Chris@87 3088 if isinstance(indx, basestring):
Chris@87 3089 ndarray.__setitem__(_data, indx, value)
Chris@87 3090 if _mask is nomask:
Chris@87 3091 self._mask = _mask = make_mask_none(self.shape, self.dtype)
Chris@87 3092 _mask[indx] = getmask(value)
Chris@87 3093 return
Chris@87 3094 #........................................
Chris@87 3095 _dtype = ndarray.__getattribute__(_data, 'dtype')
Chris@87 3096 nbfields = len(_dtype.names or ())
Chris@87 3097 #........................................
Chris@87 3098 if value is masked:
Chris@87 3099 # The mask wasn't set: create a full version...
Chris@87 3100 if _mask is nomask:
Chris@87 3101 _mask = self._mask = make_mask_none(self.shape, _dtype)
Chris@87 3102 # Now, set the mask to its value.
Chris@87 3103 if nbfields:
Chris@87 3104 _mask[indx] = tuple([True] * nbfields)
Chris@87 3105 else:
Chris@87 3106 _mask[indx] = True
Chris@87 3107 if not self._isfield:
Chris@87 3108 self._sharedmask = False
Chris@87 3109 return
Chris@87 3110 #........................................
Chris@87 3111 # Get the _data part of the new value
Chris@87 3112 dval = value
Chris@87 3113 # Get the _mask part of the new value
Chris@87 3114 mval = getattr(value, '_mask', nomask)
Chris@87 3115 if nbfields and mval is nomask:
Chris@87 3116 mval = tuple([False] * nbfields)
Chris@87 3117 if _mask is nomask:
Chris@87 3118 # Set the data, then the mask
Chris@87 3119 ndarray.__setitem__(_data, indx, dval)
Chris@87 3120 if mval is not nomask:
Chris@87 3121 _mask = self._mask = make_mask_none(self.shape, _dtype)
Chris@87 3122 ndarray.__setitem__(_mask, indx, mval)
Chris@87 3123 elif not self._hardmask:
Chris@87 3124 # Unshare the mask if necessary to avoid propagation
Chris@87 3125 if not self._isfield:
Chris@87 3126 self.unshare_mask()
Chris@87 3127 _mask = ndarray.__getattribute__(self, '_mask')
Chris@87 3128 # Set the data, then the mask
Chris@87 3129 ndarray.__setitem__(_data, indx, dval)
Chris@87 3130 ndarray.__setitem__(_mask, indx, mval)
Chris@87 3131 elif hasattr(indx, 'dtype') and (indx.dtype == MaskType):
Chris@87 3132 indx = indx * umath.logical_not(_mask)
Chris@87 3133 ndarray.__setitem__(_data, indx, dval)
Chris@87 3134 else:
Chris@87 3135 if nbfields:
Chris@87 3136 err_msg = "Flexible 'hard' masks are not yet supported..."
Chris@87 3137 raise NotImplementedError(err_msg)
Chris@87 3138 mindx = mask_or(_mask[indx], mval, copy=True)
Chris@87 3139 dindx = self._data[indx]
Chris@87 3140 if dindx.size > 1:
Chris@87 3141 np.copyto(dindx, dval, where=~mindx)
Chris@87 3142 elif mindx is nomask:
Chris@87 3143 dindx = dval
Chris@87 3144 ndarray.__setitem__(_data, indx, dindx)
Chris@87 3145 _mask[indx] = mindx
Chris@87 3146 return
Chris@87 3147
Chris@87 3148
Chris@87 3149 def __getslice__(self, i, j):
Chris@87 3150 """x.__getslice__(i, j) <==> x[i:j]
Chris@87 3151
Chris@87 3152 Return the slice described by (i, j). The use of negative
Chris@87 3153 indices is not supported.
Chris@87 3154
Chris@87 3155 """
Chris@87 3156 return self.__getitem__(slice(i, j))
Chris@87 3157
Chris@87 3158 def __setslice__(self, i, j, value):
Chris@87 3159 """x.__setslice__(i, j, value) <==> x[i:j]=value
Chris@87 3160
Chris@87 3161 Set the slice (i,j) of a to value. If value is masked, mask
Chris@87 3162 those locations.
Chris@87 3163
Chris@87 3164 """
Chris@87 3165 self.__setitem__(slice(i, j), value)
Chris@87 3166
Chris@87 3167
Chris@87 3168 def __setmask__(self, mask, copy=False):
Chris@87 3169 """Set the mask.
Chris@87 3170
Chris@87 3171 """
Chris@87 3172 idtype = ndarray.__getattribute__(self, 'dtype')
Chris@87 3173 current_mask = ndarray.__getattribute__(self, '_mask')
Chris@87 3174 if mask is masked:
Chris@87 3175 mask = True
Chris@87 3176 # Make sure the mask is set
Chris@87 3177 if (current_mask is nomask):
Chris@87 3178 # Just don't do anything is there's nothing to do...
Chris@87 3179 if mask is nomask:
Chris@87 3180 return
Chris@87 3181 current_mask = self._mask = make_mask_none(self.shape, idtype)
Chris@87 3182 # No named fields.........
Chris@87 3183 if idtype.names is None:
Chris@87 3184 # Hardmask: don't unmask the data
Chris@87 3185 if self._hardmask:
Chris@87 3186 current_mask |= mask
Chris@87 3187 # Softmask: set everything to False
Chris@87 3188 # If it's obviously a compatible scalar, use a quick update
Chris@87 3189 # method...
Chris@87 3190 elif isinstance(mask, (int, float, np.bool_, np.number)):
Chris@87 3191 current_mask[...] = mask
Chris@87 3192 # ...otherwise fall back to the slower, general purpose way.
Chris@87 3193 else:
Chris@87 3194 current_mask.flat = mask
Chris@87 3195 # Named fields w/ ............
Chris@87 3196 else:
Chris@87 3197 mdtype = current_mask.dtype
Chris@87 3198 mask = np.array(mask, copy=False)
Chris@87 3199 # Mask is a singleton
Chris@87 3200 if not mask.ndim:
Chris@87 3201 # It's a boolean : make a record
Chris@87 3202 if mask.dtype.kind == 'b':
Chris@87 3203 mask = np.array(tuple([mask.item()]*len(mdtype)),
Chris@87 3204 dtype=mdtype)
Chris@87 3205 # It's a record: make sure the dtype is correct
Chris@87 3206 else:
Chris@87 3207 mask = mask.astype(mdtype)
Chris@87 3208 # Mask is a sequence
Chris@87 3209 else:
Chris@87 3210 # Make sure the new mask is a ndarray with the proper dtype
Chris@87 3211 try:
Chris@87 3212 mask = np.array(mask, copy=copy, dtype=mdtype)
Chris@87 3213 # Or assume it's a sequence of bool/int
Chris@87 3214 except TypeError:
Chris@87 3215 mask = np.array([tuple([m] * len(mdtype)) for m in mask],
Chris@87 3216 dtype=mdtype)
Chris@87 3217 # Hardmask: don't unmask the data
Chris@87 3218 if self._hardmask:
Chris@87 3219 for n in idtype.names:
Chris@87 3220 current_mask[n] |= mask[n]
Chris@87 3221 # Softmask: set everything to False
Chris@87 3222 # If it's obviously a compatible scalar, use a quick update
Chris@87 3223 # method...
Chris@87 3224 elif isinstance(mask, (int, float, np.bool_, np.number)):
Chris@87 3225 current_mask[...] = mask
Chris@87 3226 # ...otherwise fall back to the slower, general purpose way.
Chris@87 3227 else:
Chris@87 3228 current_mask.flat = mask
Chris@87 3229 # Reshape if needed
Chris@87 3230 if current_mask.shape:
Chris@87 3231 current_mask.shape = self.shape
Chris@87 3232 return
Chris@87 3233 _set_mask = __setmask__
Chris@87 3234 #....
Chris@87 3235 def _get_mask(self):
Chris@87 3236 """Return the current mask.
Chris@87 3237
Chris@87 3238 """
Chris@87 3239 # We could try to force a reshape, but that wouldn't work in some cases.
Chris@87 3240 # return self._mask.reshape(self.shape)
Chris@87 3241 return self._mask
Chris@87 3242 mask = property(fget=_get_mask, fset=__setmask__, doc="Mask")
Chris@87 3243
Chris@87 3244
Chris@87 3245 def _get_recordmask(self):
Chris@87 3246 """
Chris@87 3247 Return the mask of the records.
Chris@87 3248 A record is masked when all the fields are masked.
Chris@87 3249
Chris@87 3250 """
Chris@87 3251 _mask = ndarray.__getattribute__(self, '_mask').view(ndarray)
Chris@87 3252 if _mask.dtype.names is None:
Chris@87 3253 return _mask
Chris@87 3254 return np.all(flatten_structured_array(_mask), axis= -1)
Chris@87 3255
Chris@87 3256
Chris@87 3257 def _set_recordmask(self):
Chris@87 3258 """Return the mask of the records.
Chris@87 3259 A record is masked when all the fields are masked.
Chris@87 3260
Chris@87 3261 """
Chris@87 3262 raise NotImplementedError("Coming soon: setting the mask per records!")
Chris@87 3263 recordmask = property(fget=_get_recordmask)
Chris@87 3264
Chris@87 3265 #............................................
Chris@87 3266 def harden_mask(self):
Chris@87 3267 """
Chris@87 3268 Force the mask to hard.
Chris@87 3269
Chris@87 3270 Whether the mask of a masked array is hard or soft is determined by
Chris@87 3271 its `hardmask` property. `harden_mask` sets `hardmask` to True.
Chris@87 3272
Chris@87 3273 See Also
Chris@87 3274 --------
Chris@87 3275 hardmask
Chris@87 3276
Chris@87 3277 """
Chris@87 3278 self._hardmask = True
Chris@87 3279 return self
Chris@87 3280
Chris@87 3281 def soften_mask(self):
Chris@87 3282 """
Chris@87 3283 Force the mask to soft.
Chris@87 3284
Chris@87 3285 Whether the mask of a masked array is hard or soft is determined by
Chris@87 3286 its `hardmask` property. `soften_mask` sets `hardmask` to False.
Chris@87 3287
Chris@87 3288 See Also
Chris@87 3289 --------
Chris@87 3290 hardmask
Chris@87 3291
Chris@87 3292 """
Chris@87 3293 self._hardmask = False
Chris@87 3294 return self
Chris@87 3295
Chris@87 3296 hardmask = property(fget=lambda self: self._hardmask,
Chris@87 3297 doc="Hardness of the mask")
Chris@87 3298
Chris@87 3299
Chris@87 3300 def unshare_mask(self):
Chris@87 3301 """
Chris@87 3302 Copy the mask and set the sharedmask flag to False.
Chris@87 3303
Chris@87 3304 Whether the mask is shared between masked arrays can be seen from
Chris@87 3305 the `sharedmask` property. `unshare_mask` ensures the mask is not shared.
Chris@87 3306 A copy of the mask is only made if it was shared.
Chris@87 3307
Chris@87 3308 See Also
Chris@87 3309 --------
Chris@87 3310 sharedmask
Chris@87 3311
Chris@87 3312 """
Chris@87 3313 if self._sharedmask:
Chris@87 3314 self._mask = self._mask.copy()
Chris@87 3315 self._sharedmask = False
Chris@87 3316 return self
Chris@87 3317
Chris@87 3318 sharedmask = property(fget=lambda self: self._sharedmask,
Chris@87 3319 doc="Share status of the mask (read-only).")
Chris@87 3320
Chris@87 3321 def shrink_mask(self):
Chris@87 3322 """
Chris@87 3323 Reduce a mask to nomask when possible.
Chris@87 3324
Chris@87 3325 Parameters
Chris@87 3326 ----------
Chris@87 3327 None
Chris@87 3328
Chris@87 3329 Returns
Chris@87 3330 -------
Chris@87 3331 None
Chris@87 3332
Chris@87 3333 Examples
Chris@87 3334 --------
Chris@87 3335 >>> x = np.ma.array([[1,2 ], [3, 4]], mask=[0]*4)
Chris@87 3336 >>> x.mask
Chris@87 3337 array([[False, False],
Chris@87 3338 [False, False]], dtype=bool)
Chris@87 3339 >>> x.shrink_mask()
Chris@87 3340 >>> x.mask
Chris@87 3341 False
Chris@87 3342
Chris@87 3343 """
Chris@87 3344 m = self._mask
Chris@87 3345 if m.ndim and not m.any():
Chris@87 3346 self._mask = nomask
Chris@87 3347 return self
Chris@87 3348
Chris@87 3349 #............................................
Chris@87 3350
Chris@87 3351 baseclass = property(fget=lambda self:self._baseclass,
Chris@87 3352 doc="Class of the underlying data (read-only).")
Chris@87 3353
Chris@87 3354 def _get_data(self):
Chris@87 3355 """Return the current data, as a view of the original
Chris@87 3356 underlying data.
Chris@87 3357
Chris@87 3358 """
Chris@87 3359 return ndarray.view(self, self._baseclass)
Chris@87 3360 _data = property(fget=_get_data)
Chris@87 3361 data = property(fget=_get_data)
Chris@87 3362
Chris@87 3363 def _get_flat(self):
Chris@87 3364 "Return a flat iterator."
Chris@87 3365 return MaskedIterator(self)
Chris@87 3366 #
Chris@87 3367 def _set_flat (self, value):
Chris@87 3368 "Set a flattened version of self to value."
Chris@87 3369 y = self.ravel()
Chris@87 3370 y[:] = value
Chris@87 3371 #
Chris@87 3372 flat = property(fget=_get_flat, fset=_set_flat,
Chris@87 3373 doc="Flat version of the array.")
Chris@87 3374
Chris@87 3375
Chris@87 3376 def get_fill_value(self):
Chris@87 3377 """
Chris@87 3378 Return the filling value of the masked array.
Chris@87 3379
Chris@87 3380 Returns
Chris@87 3381 -------
Chris@87 3382 fill_value : scalar
Chris@87 3383 The filling value.
Chris@87 3384
Chris@87 3385 Examples
Chris@87 3386 --------
Chris@87 3387 >>> for dt in [np.int32, np.int64, np.float64, np.complex128]:
Chris@87 3388 ... np.ma.array([0, 1], dtype=dt).get_fill_value()
Chris@87 3389 ...
Chris@87 3390 999999
Chris@87 3391 999999
Chris@87 3392 1e+20
Chris@87 3393 (1e+20+0j)
Chris@87 3394
Chris@87 3395 >>> x = np.ma.array([0, 1.], fill_value=-np.inf)
Chris@87 3396 >>> x.get_fill_value()
Chris@87 3397 -inf
Chris@87 3398
Chris@87 3399 """
Chris@87 3400 if self._fill_value is None:
Chris@87 3401 self._fill_value = _check_fill_value(None, self.dtype)
Chris@87 3402 return self._fill_value[()]
Chris@87 3403
Chris@87 3404 def set_fill_value(self, value=None):
Chris@87 3405 """
Chris@87 3406 Set the filling value of the masked array.
Chris@87 3407
Chris@87 3408 Parameters
Chris@87 3409 ----------
Chris@87 3410 value : scalar, optional
Chris@87 3411 The new filling value. Default is None, in which case a default
Chris@87 3412 based on the data type is used.
Chris@87 3413
Chris@87 3414 See Also
Chris@87 3415 --------
Chris@87 3416 ma.set_fill_value : Equivalent function.
Chris@87 3417
Chris@87 3418 Examples
Chris@87 3419 --------
Chris@87 3420 >>> x = np.ma.array([0, 1.], fill_value=-np.inf)
Chris@87 3421 >>> x.fill_value
Chris@87 3422 -inf
Chris@87 3423 >>> x.set_fill_value(np.pi)
Chris@87 3424 >>> x.fill_value
Chris@87 3425 3.1415926535897931
Chris@87 3426
Chris@87 3427 Reset to default:
Chris@87 3428
Chris@87 3429 >>> x.set_fill_value()
Chris@87 3430 >>> x.fill_value
Chris@87 3431 1e+20
Chris@87 3432
Chris@87 3433 """
Chris@87 3434 target = _check_fill_value(value, self.dtype)
Chris@87 3435 _fill_value = self._fill_value
Chris@87 3436 if _fill_value is None:
Chris@87 3437 # Create the attribute if it was undefined
Chris@87 3438 self._fill_value = target
Chris@87 3439 else:
Chris@87 3440 # Don't overwrite the attribute, just fill it (for propagation)
Chris@87 3441 _fill_value[()] = target
Chris@87 3442
Chris@87 3443 fill_value = property(fget=get_fill_value, fset=set_fill_value,
Chris@87 3444 doc="Filling value.")
Chris@87 3445
Chris@87 3446
Chris@87 3447 def filled(self, fill_value=None):
Chris@87 3448 """
Chris@87 3449 Return a copy of self, with masked values filled with a given value.
Chris@87 3450
Chris@87 3451 Parameters
Chris@87 3452 ----------
Chris@87 3453 fill_value : scalar, optional
Chris@87 3454 The value to use for invalid entries (None by default).
Chris@87 3455 If None, the `fill_value` attribute of the array is used instead.
Chris@87 3456
Chris@87 3457 Returns
Chris@87 3458 -------
Chris@87 3459 filled_array : ndarray
Chris@87 3460 A copy of ``self`` with invalid entries replaced by *fill_value*
Chris@87 3461 (be it the function argument or the attribute of ``self``.
Chris@87 3462
Chris@87 3463 Notes
Chris@87 3464 -----
Chris@87 3465 The result is **not** a MaskedArray!
Chris@87 3466
Chris@87 3467 Examples
Chris@87 3468 --------
Chris@87 3469 >>> x = np.ma.array([1,2,3,4,5], mask=[0,0,1,0,1], fill_value=-999)
Chris@87 3470 >>> x.filled()
Chris@87 3471 array([1, 2, -999, 4, -999])
Chris@87 3472 >>> type(x.filled())
Chris@87 3473 <type 'numpy.ndarray'>
Chris@87 3474
Chris@87 3475 Subclassing is preserved. This means that if the data part of the masked
Chris@87 3476 array is a matrix, `filled` returns a matrix:
Chris@87 3477
Chris@87 3478 >>> x = np.ma.array(np.matrix([[1, 2], [3, 4]]), mask=[[0, 1], [1, 0]])
Chris@87 3479 >>> x.filled()
Chris@87 3480 matrix([[ 1, 999999],
Chris@87 3481 [999999, 4]])
Chris@87 3482
Chris@87 3483 """
Chris@87 3484 m = self._mask
Chris@87 3485 if m is nomask:
Chris@87 3486 return self._data
Chris@87 3487 #
Chris@87 3488 if fill_value is None:
Chris@87 3489 fill_value = self.fill_value
Chris@87 3490 else:
Chris@87 3491 fill_value = _check_fill_value(fill_value, self.dtype)
Chris@87 3492 #
Chris@87 3493 if self is masked_singleton:
Chris@87 3494 return np.asanyarray(fill_value)
Chris@87 3495 #
Chris@87 3496 if m.dtype.names:
Chris@87 3497 result = self._data.copy('K')
Chris@87 3498 _recursive_filled(result, self._mask, fill_value)
Chris@87 3499 elif not m.any():
Chris@87 3500 return self._data
Chris@87 3501 else:
Chris@87 3502 result = self._data.copy('K')
Chris@87 3503 try:
Chris@87 3504 np.copyto(result, fill_value, where=m)
Chris@87 3505 except (TypeError, AttributeError):
Chris@87 3506 fill_value = narray(fill_value, dtype=object)
Chris@87 3507 d = result.astype(object)
Chris@87 3508 result = np.choose(m, (d, fill_value))
Chris@87 3509 except IndexError:
Chris@87 3510 #ok, if scalar
Chris@87 3511 if self._data.shape:
Chris@87 3512 raise
Chris@87 3513 elif m:
Chris@87 3514 result = np.array(fill_value, dtype=self.dtype)
Chris@87 3515 else:
Chris@87 3516 result = self._data
Chris@87 3517 return result
Chris@87 3518
Chris@87 3519 def compressed(self):
Chris@87 3520 """
Chris@87 3521 Return all the non-masked data as a 1-D array.
Chris@87 3522
Chris@87 3523 Returns
Chris@87 3524 -------
Chris@87 3525 data : ndarray
Chris@87 3526 A new `ndarray` holding the non-masked data is returned.
Chris@87 3527
Chris@87 3528 Notes
Chris@87 3529 -----
Chris@87 3530 The result is **not** a MaskedArray!
Chris@87 3531
Chris@87 3532 Examples
Chris@87 3533 --------
Chris@87 3534 >>> x = np.ma.array(np.arange(5), mask=[0]*2 + [1]*3)
Chris@87 3535 >>> x.compressed()
Chris@87 3536 array([0, 1])
Chris@87 3537 >>> type(x.compressed())
Chris@87 3538 <type 'numpy.ndarray'>
Chris@87 3539
Chris@87 3540 """
Chris@87 3541 data = ndarray.ravel(self._data)
Chris@87 3542 if self._mask is not nomask:
Chris@87 3543 data = data.compress(np.logical_not(ndarray.ravel(self._mask)))
Chris@87 3544 return data
Chris@87 3545
Chris@87 3546
Chris@87 3547 def compress(self, condition, axis=None, out=None):
Chris@87 3548 """
Chris@87 3549 Return `a` where condition is ``True``.
Chris@87 3550
Chris@87 3551 If condition is a `MaskedArray`, missing values are considered
Chris@87 3552 as ``False``.
Chris@87 3553
Chris@87 3554 Parameters
Chris@87 3555 ----------
Chris@87 3556 condition : var
Chris@87 3557 Boolean 1-d array selecting which entries to return. If len(condition)
Chris@87 3558 is less than the size of a along the axis, then output is truncated
Chris@87 3559 to length of condition array.
Chris@87 3560 axis : {None, int}, optional
Chris@87 3561 Axis along which the operation must be performed.
Chris@87 3562 out : {None, ndarray}, optional
Chris@87 3563 Alternative output array in which to place the result. It must have
Chris@87 3564 the same shape as the expected output but the type will be cast if
Chris@87 3565 necessary.
Chris@87 3566
Chris@87 3567 Returns
Chris@87 3568 -------
Chris@87 3569 result : MaskedArray
Chris@87 3570 A :class:`MaskedArray` object.
Chris@87 3571
Chris@87 3572 Notes
Chris@87 3573 -----
Chris@87 3574 Please note the difference with :meth:`compressed` !
Chris@87 3575 The output of :meth:`compress` has a mask, the output of
Chris@87 3576 :meth:`compressed` does not.
Chris@87 3577
Chris@87 3578 Examples
Chris@87 3579 --------
Chris@87 3580 >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
Chris@87 3581 >>> print x
Chris@87 3582 [[1 -- 3]
Chris@87 3583 [-- 5 --]
Chris@87 3584 [7 -- 9]]
Chris@87 3585 >>> x.compress([1, 0, 1])
Chris@87 3586 masked_array(data = [1 3],
Chris@87 3587 mask = [False False],
Chris@87 3588 fill_value=999999)
Chris@87 3589
Chris@87 3590 >>> x.compress([1, 0, 1], axis=1)
Chris@87 3591 masked_array(data =
Chris@87 3592 [[1 3]
Chris@87 3593 [-- --]
Chris@87 3594 [7 9]],
Chris@87 3595 mask =
Chris@87 3596 [[False False]
Chris@87 3597 [ True True]
Chris@87 3598 [False False]],
Chris@87 3599 fill_value=999999)
Chris@87 3600
Chris@87 3601 """
Chris@87 3602 # Get the basic components
Chris@87 3603 (_data, _mask) = (self._data, self._mask)
Chris@87 3604 # Force the condition to a regular ndarray (forget the missing values...)
Chris@87 3605 condition = np.array(condition, copy=False, subok=False)
Chris@87 3606 #
Chris@87 3607 _new = _data.compress(condition, axis=axis, out=out).view(type(self))
Chris@87 3608 _new._update_from(self)
Chris@87 3609 if _mask is not nomask:
Chris@87 3610 _new._mask = _mask.compress(condition, axis=axis)
Chris@87 3611 return _new
Chris@87 3612
Chris@87 3613 #............................................
Chris@87 3614 def __str__(self):
Chris@87 3615 """String representation.
Chris@87 3616
Chris@87 3617 """
Chris@87 3618 if masked_print_option.enabled():
Chris@87 3619 f = masked_print_option
Chris@87 3620 if self is masked:
Chris@87 3621 return str(f)
Chris@87 3622 m = self._mask
Chris@87 3623 if m is nomask:
Chris@87 3624 res = self._data
Chris@87 3625 else:
Chris@87 3626 if m.shape == ():
Chris@87 3627 if m.dtype.names:
Chris@87 3628 m = m.view((bool, len(m.dtype)))
Chris@87 3629 if m.any():
Chris@87 3630 return str(tuple((f if _m else _d) for _d, _m in
Chris@87 3631 zip(self._data.tolist(), m)))
Chris@87 3632 else:
Chris@87 3633 return str(self._data)
Chris@87 3634 elif m:
Chris@87 3635 return str(f)
Chris@87 3636 else:
Chris@87 3637 return str(self._data)
Chris@87 3638 # convert to object array to make filled work
Chris@87 3639 names = self.dtype.names
Chris@87 3640 if names is None:
Chris@87 3641 res = self._data.astype("O")
Chris@87 3642 res.view(ndarray)[m] = f
Chris@87 3643 else:
Chris@87 3644 rdtype = _recursive_make_descr(self.dtype, "O")
Chris@87 3645 res = self._data.astype(rdtype)
Chris@87 3646 _recursive_printoption(res, m, f)
Chris@87 3647 else:
Chris@87 3648 res = self.filled(self.fill_value)
Chris@87 3649 return str(res)
Chris@87 3650
Chris@87 3651 def __repr__(self):
Chris@87 3652 """Literal string representation.
Chris@87 3653
Chris@87 3654 """
Chris@87 3655 n = len(self.shape)
Chris@87 3656 if self._baseclass is np.ndarray:
Chris@87 3657 name = 'array'
Chris@87 3658 else:
Chris@87 3659 name = self._baseclass.__name__
Chris@87 3660
Chris@87 3661 parameters = dict(name=name, nlen=" " * len(name),
Chris@87 3662 data=str(self), mask=str(self._mask),
Chris@87 3663 fill=str(self.fill_value), dtype=str(self.dtype))
Chris@87 3664 if self.dtype.names:
Chris@87 3665 if n <= 1:
Chris@87 3666 return _print_templates['short_flx'] % parameters
Chris@87 3667 return _print_templates['long_flx'] % parameters
Chris@87 3668 elif n <= 1:
Chris@87 3669 return _print_templates['short_std'] % parameters
Chris@87 3670 return _print_templates['long_std'] % parameters
Chris@87 3671
Chris@87 3672 def __eq__(self, other):
Chris@87 3673 "Check whether other equals self elementwise"
Chris@87 3674 if self is masked:
Chris@87 3675 return masked
Chris@87 3676 omask = getattr(other, '_mask', nomask)
Chris@87 3677 if omask is nomask:
Chris@87 3678 check = ndarray.__eq__(self.filled(0), other)
Chris@87 3679 try:
Chris@87 3680 check = check.view(type(self))
Chris@87 3681 check._mask = self._mask
Chris@87 3682 except AttributeError:
Chris@87 3683 # Dang, we have a bool instead of an array: return the bool
Chris@87 3684 return check
Chris@87 3685 else:
Chris@87 3686 odata = filled(other, 0)
Chris@87 3687 check = ndarray.__eq__(self.filled(0), odata).view(type(self))
Chris@87 3688 if self._mask is nomask:
Chris@87 3689 check._mask = omask
Chris@87 3690 else:
Chris@87 3691 mask = mask_or(self._mask, omask)
Chris@87 3692 if mask.dtype.names:
Chris@87 3693 if mask.size > 1:
Chris@87 3694 axis = 1
Chris@87 3695 else:
Chris@87 3696 axis = None
Chris@87 3697 try:
Chris@87 3698 mask = mask.view((bool_, len(self.dtype))).all(axis)
Chris@87 3699 except ValueError:
Chris@87 3700 mask = np.all([[f[n].all() for n in mask.dtype.names]
Chris@87 3701 for f in mask], axis=axis)
Chris@87 3702 check._mask = mask
Chris@87 3703 return check
Chris@87 3704 #
Chris@87 3705 def __ne__(self, other):
Chris@87 3706 "Check whether other doesn't equal self elementwise"
Chris@87 3707 if self is masked:
Chris@87 3708 return masked
Chris@87 3709 omask = getattr(other, '_mask', nomask)
Chris@87 3710 if omask is nomask:
Chris@87 3711 check = ndarray.__ne__(self.filled(0), other)
Chris@87 3712 try:
Chris@87 3713 check = check.view(type(self))
Chris@87 3714 check._mask = self._mask
Chris@87 3715 except AttributeError:
Chris@87 3716 # In case check is a boolean (or a numpy.bool)
Chris@87 3717 return check
Chris@87 3718 else:
Chris@87 3719 odata = filled(other, 0)
Chris@87 3720 check = ndarray.__ne__(self.filled(0), odata).view(type(self))
Chris@87 3721 if self._mask is nomask:
Chris@87 3722 check._mask = omask
Chris@87 3723 else:
Chris@87 3724 mask = mask_or(self._mask, omask)
Chris@87 3725 if mask.dtype.names:
Chris@87 3726 if mask.size > 1:
Chris@87 3727 axis = 1
Chris@87 3728 else:
Chris@87 3729 axis = None
Chris@87 3730 try:
Chris@87 3731 mask = mask.view((bool_, len(self.dtype))).all(axis)
Chris@87 3732 except ValueError:
Chris@87 3733 mask = np.all([[f[n].all() for n in mask.dtype.names]
Chris@87 3734 for f in mask], axis=axis)
Chris@87 3735 check._mask = mask
Chris@87 3736 return check
Chris@87 3737 #
Chris@87 3738 def __add__(self, other):
Chris@87 3739 "Add other to self, and return a new masked array."
Chris@87 3740 return add(self, other)
Chris@87 3741 #
Chris@87 3742 def __radd__(self, other):
Chris@87 3743 "Add other to self, and return a new masked array."
Chris@87 3744 return add(self, other)
Chris@87 3745 #
Chris@87 3746 def __sub__(self, other):
Chris@87 3747 "Subtract other to self, and return a new masked array."
Chris@87 3748 return subtract(self, other)
Chris@87 3749 #
Chris@87 3750 def __rsub__(self, other):
Chris@87 3751 "Subtract other to self, and return a new masked array."
Chris@87 3752 return subtract(other, self)
Chris@87 3753 #
Chris@87 3754 def __mul__(self, other):
Chris@87 3755 "Multiply other by self, and return a new masked array."
Chris@87 3756 return multiply(self, other)
Chris@87 3757 #
Chris@87 3758 def __rmul__(self, other):
Chris@87 3759 "Multiply other by self, and return a new masked array."
Chris@87 3760 return multiply(self, other)
Chris@87 3761 #
Chris@87 3762 def __div__(self, other):
Chris@87 3763 "Divide other into self, and return a new masked array."
Chris@87 3764 return divide(self, other)
Chris@87 3765 #
Chris@87 3766 def __truediv__(self, other):
Chris@87 3767 "Divide other into self, and return a new masked array."
Chris@87 3768 return true_divide(self, other)
Chris@87 3769 #
Chris@87 3770 def __rtruediv__(self, other):
Chris@87 3771 "Divide other into self, and return a new masked array."
Chris@87 3772 return true_divide(other, self)
Chris@87 3773 #
Chris@87 3774 def __floordiv__(self, other):
Chris@87 3775 "Divide other into self, and return a new masked array."
Chris@87 3776 return floor_divide(self, other)
Chris@87 3777 #
Chris@87 3778 def __rfloordiv__(self, other):
Chris@87 3779 "Divide other into self, and return a new masked array."
Chris@87 3780 return floor_divide(other, self)
Chris@87 3781 #
Chris@87 3782 def __pow__(self, other):
Chris@87 3783 "Raise self to the power other, masking the potential NaNs/Infs"
Chris@87 3784 return power(self, other)
Chris@87 3785 #
Chris@87 3786 def __rpow__(self, other):
Chris@87 3787 "Raise self to the power other, masking the potential NaNs/Infs"
Chris@87 3788 return power(other, self)
Chris@87 3789 #............................................
Chris@87 3790 def __iadd__(self, other):
Chris@87 3791 "Add other to self in-place."
Chris@87 3792 m = getmask(other)
Chris@87 3793 if self._mask is nomask:
Chris@87 3794 if m is not nomask and m.any():
Chris@87 3795 self._mask = make_mask_none(self.shape, self.dtype)
Chris@87 3796 self._mask += m
Chris@87 3797 else:
Chris@87 3798 if m is not nomask:
Chris@87 3799 self._mask += m
Chris@87 3800 ndarray.__iadd__(self._data, np.where(self._mask, 0, getdata(other)))
Chris@87 3801 return self
Chris@87 3802 #....
Chris@87 3803 def __isub__(self, other):
Chris@87 3804 "Subtract other from self in-place."
Chris@87 3805 m = getmask(other)
Chris@87 3806 if self._mask is nomask:
Chris@87 3807 if m is not nomask and m.any():
Chris@87 3808 self._mask = make_mask_none(self.shape, self.dtype)
Chris@87 3809 self._mask += m
Chris@87 3810 elif m is not nomask:
Chris@87 3811 self._mask += m
Chris@87 3812 ndarray.__isub__(self._data, np.where(self._mask, 0, getdata(other)))
Chris@87 3813 return self
Chris@87 3814 #....
Chris@87 3815 def __imul__(self, other):
Chris@87 3816 "Multiply self by other in-place."
Chris@87 3817 m = getmask(other)
Chris@87 3818 if self._mask is nomask:
Chris@87 3819 if m is not nomask and m.any():
Chris@87 3820 self._mask = make_mask_none(self.shape, self.dtype)
Chris@87 3821 self._mask += m
Chris@87 3822 elif m is not nomask:
Chris@87 3823 self._mask += m
Chris@87 3824 ndarray.__imul__(self._data, np.where(self._mask, 1, getdata(other)))
Chris@87 3825 return self
Chris@87 3826 #....
Chris@87 3827 def __idiv__(self, other):
Chris@87 3828 "Divide self by other in-place."
Chris@87 3829 other_data = getdata(other)
Chris@87 3830 dom_mask = _DomainSafeDivide().__call__(self._data, other_data)
Chris@87 3831 other_mask = getmask(other)
Chris@87 3832 new_mask = mask_or(other_mask, dom_mask)
Chris@87 3833 # The following 3 lines control the domain filling
Chris@87 3834 if dom_mask.any():
Chris@87 3835 (_, fval) = ufunc_fills[np.divide]
Chris@87 3836 other_data = np.where(dom_mask, fval, other_data)
Chris@87 3837 # self._mask = mask_or(self._mask, new_mask)
Chris@87 3838 self._mask |= new_mask
Chris@87 3839 ndarray.__idiv__(self._data, np.where(self._mask, 1, other_data))
Chris@87 3840 return self
Chris@87 3841 #....
Chris@87 3842 def __ifloordiv__(self, other):
Chris@87 3843 "Floor divide self by other in-place."
Chris@87 3844 other_data = getdata(other)
Chris@87 3845 dom_mask = _DomainSafeDivide().__call__(self._data, other_data)
Chris@87 3846 other_mask = getmask(other)
Chris@87 3847 new_mask = mask_or(other_mask, dom_mask)
Chris@87 3848 # The following 3 lines control the domain filling
Chris@87 3849 if dom_mask.any():
Chris@87 3850 (_, fval) = ufunc_fills[np.floor_divide]
Chris@87 3851 other_data = np.where(dom_mask, fval, other_data)
Chris@87 3852 # self._mask = mask_or(self._mask, new_mask)
Chris@87 3853 self._mask |= new_mask
Chris@87 3854 ndarray.__ifloordiv__(self._data, np.where(self._mask, 1, other_data))
Chris@87 3855 return self
Chris@87 3856 #....
Chris@87 3857 def __itruediv__(self, other):
Chris@87 3858 "True divide self by other in-place."
Chris@87 3859 other_data = getdata(other)
Chris@87 3860 dom_mask = _DomainSafeDivide().__call__(self._data, other_data)
Chris@87 3861 other_mask = getmask(other)
Chris@87 3862 new_mask = mask_or(other_mask, dom_mask)
Chris@87 3863 # The following 3 lines control the domain filling
Chris@87 3864 if dom_mask.any():
Chris@87 3865 (_, fval) = ufunc_fills[np.true_divide]
Chris@87 3866 other_data = np.where(dom_mask, fval, other_data)
Chris@87 3867 # self._mask = mask_or(self._mask, new_mask)
Chris@87 3868 self._mask |= new_mask
Chris@87 3869 ndarray.__itruediv__(self._data, np.where(self._mask, 1, other_data))
Chris@87 3870 return self
Chris@87 3871 #...
Chris@87 3872 def __ipow__(self, other):
Chris@87 3873 "Raise self to the power other, in place."
Chris@87 3874 other_data = getdata(other)
Chris@87 3875 other_mask = getmask(other)
Chris@87 3876 with np.errstate(divide='ignore', invalid='ignore'):
Chris@87 3877 ndarray.__ipow__(self._data, np.where(self._mask, 1, other_data))
Chris@87 3878 invalid = np.logical_not(np.isfinite(self._data))
Chris@87 3879 if invalid.any():
Chris@87 3880 if self._mask is not nomask:
Chris@87 3881 self._mask |= invalid
Chris@87 3882 else:
Chris@87 3883 self._mask = invalid
Chris@87 3884 np.copyto(self._data, self.fill_value, where=invalid)
Chris@87 3885 new_mask = mask_or(other_mask, invalid)
Chris@87 3886 self._mask = mask_or(self._mask, new_mask)
Chris@87 3887 return self
Chris@87 3888 #............................................
Chris@87 3889 def __float__(self):
Chris@87 3890 "Convert to float."
Chris@87 3891 if self.size > 1:
Chris@87 3892 raise TypeError("Only length-1 arrays can be converted "
Chris@87 3893 "to Python scalars")
Chris@87 3894 elif self._mask:
Chris@87 3895 warnings.warn("Warning: converting a masked element to nan.")
Chris@87 3896 return np.nan
Chris@87 3897 return float(self.item())
Chris@87 3898
Chris@87 3899 def __int__(self):
Chris@87 3900 "Convert to int."
Chris@87 3901 if self.size > 1:
Chris@87 3902 raise TypeError("Only length-1 arrays can be converted "
Chris@87 3903 "to Python scalars")
Chris@87 3904 elif self._mask:
Chris@87 3905 raise MaskError('Cannot convert masked element to a Python int.')
Chris@87 3906 return int(self.item())
Chris@87 3907
Chris@87 3908
Chris@87 3909 def get_imag(self):
Chris@87 3910 """
Chris@87 3911 Return the imaginary part of the masked array.
Chris@87 3912
Chris@87 3913 The returned array is a view on the imaginary part of the `MaskedArray`
Chris@87 3914 whose `get_imag` method is called.
Chris@87 3915
Chris@87 3916 Parameters
Chris@87 3917 ----------
Chris@87 3918 None
Chris@87 3919
Chris@87 3920 Returns
Chris@87 3921 -------
Chris@87 3922 result : MaskedArray
Chris@87 3923 The imaginary part of the masked array.
Chris@87 3924
Chris@87 3925 See Also
Chris@87 3926 --------
Chris@87 3927 get_real, real, imag
Chris@87 3928
Chris@87 3929 Examples
Chris@87 3930 --------
Chris@87 3931 >>> x = np.ma.array([1+1.j, -2j, 3.45+1.6j], mask=[False, True, False])
Chris@87 3932 >>> x.get_imag()
Chris@87 3933 masked_array(data = [1.0 -- 1.6],
Chris@87 3934 mask = [False True False],
Chris@87 3935 fill_value = 1e+20)
Chris@87 3936
Chris@87 3937 """
Chris@87 3938 result = self._data.imag.view(type(self))
Chris@87 3939 result.__setmask__(self._mask)
Chris@87 3940 return result
Chris@87 3941 imag = property(fget=get_imag, doc="Imaginary part.")
Chris@87 3942
Chris@87 3943 def get_real(self):
Chris@87 3944 """
Chris@87 3945 Return the real part of the masked array.
Chris@87 3946
Chris@87 3947 The returned array is a view on the real part of the `MaskedArray`
Chris@87 3948 whose `get_real` method is called.
Chris@87 3949
Chris@87 3950 Parameters
Chris@87 3951 ----------
Chris@87 3952 None
Chris@87 3953
Chris@87 3954 Returns
Chris@87 3955 -------
Chris@87 3956 result : MaskedArray
Chris@87 3957 The real part of the masked array.
Chris@87 3958
Chris@87 3959 See Also
Chris@87 3960 --------
Chris@87 3961 get_imag, real, imag
Chris@87 3962
Chris@87 3963 Examples
Chris@87 3964 --------
Chris@87 3965 >>> x = np.ma.array([1+1.j, -2j, 3.45+1.6j], mask=[False, True, False])
Chris@87 3966 >>> x.get_real()
Chris@87 3967 masked_array(data = [1.0 -- 3.45],
Chris@87 3968 mask = [False True False],
Chris@87 3969 fill_value = 1e+20)
Chris@87 3970
Chris@87 3971 """
Chris@87 3972 result = self._data.real.view(type(self))
Chris@87 3973 result.__setmask__(self._mask)
Chris@87 3974 return result
Chris@87 3975 real = property(fget=get_real, doc="Real part")
Chris@87 3976
Chris@87 3977
Chris@87 3978 #............................................
Chris@87 3979 def count(self, axis=None):
Chris@87 3980 """
Chris@87 3981 Count the non-masked elements of the array along the given axis.
Chris@87 3982
Chris@87 3983 Parameters
Chris@87 3984 ----------
Chris@87 3985 axis : int, optional
Chris@87 3986 Axis along which to count the non-masked elements. If `axis` is
Chris@87 3987 `None`, all non-masked elements are counted.
Chris@87 3988
Chris@87 3989 Returns
Chris@87 3990 -------
Chris@87 3991 result : int or ndarray
Chris@87 3992 If `axis` is `None`, an integer count is returned. When `axis` is
Chris@87 3993 not `None`, an array with shape determined by the lengths of the
Chris@87 3994 remaining axes, is returned.
Chris@87 3995
Chris@87 3996 See Also
Chris@87 3997 --------
Chris@87 3998 count_masked : Count masked elements in array or along a given axis.
Chris@87 3999
Chris@87 4000 Examples
Chris@87 4001 --------
Chris@87 4002 >>> import numpy.ma as ma
Chris@87 4003 >>> a = ma.arange(6).reshape((2, 3))
Chris@87 4004 >>> a[1, :] = ma.masked
Chris@87 4005 >>> a
Chris@87 4006 masked_array(data =
Chris@87 4007 [[0 1 2]
Chris@87 4008 [-- -- --]],
Chris@87 4009 mask =
Chris@87 4010 [[False False False]
Chris@87 4011 [ True True True]],
Chris@87 4012 fill_value = 999999)
Chris@87 4013 >>> a.count()
Chris@87 4014 3
Chris@87 4015
Chris@87 4016 When the `axis` keyword is specified an array of appropriate size is
Chris@87 4017 returned.
Chris@87 4018
Chris@87 4019 >>> a.count(axis=0)
Chris@87 4020 array([1, 1, 1])
Chris@87 4021 >>> a.count(axis=1)
Chris@87 4022 array([3, 0])
Chris@87 4023
Chris@87 4024 """
Chris@87 4025 m = self._mask
Chris@87 4026 s = self.shape
Chris@87 4027 if m is nomask:
Chris@87 4028 if axis is None:
Chris@87 4029 return self.size
Chris@87 4030 else:
Chris@87 4031 n = s[axis]
Chris@87 4032 t = list(s)
Chris@87 4033 del t[axis]
Chris@87 4034 return np.full(t, n, dtype=np.intp)
Chris@87 4035 n1 = np.size(m, axis)
Chris@87 4036 n2 = np.sum(m, axis=axis, dtype=np.intp)
Chris@87 4037 if axis is None:
Chris@87 4038 return (n1 - n2)
Chris@87 4039 else:
Chris@87 4040 return narray(n1 - n2)
Chris@87 4041 #............................................
Chris@87 4042 flatten = _arraymethod('flatten')
Chris@87 4043 #
Chris@87 4044 def ravel(self):
Chris@87 4045 """
Chris@87 4046 Returns a 1D version of self, as a view.
Chris@87 4047
Chris@87 4048 Returns
Chris@87 4049 -------
Chris@87 4050 MaskedArray
Chris@87 4051 Output view is of shape ``(self.size,)`` (or
Chris@87 4052 ``(np.ma.product(self.shape),)``).
Chris@87 4053
Chris@87 4054 Examples
Chris@87 4055 --------
Chris@87 4056 >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
Chris@87 4057 >>> print x
Chris@87 4058 [[1 -- 3]
Chris@87 4059 [-- 5 --]
Chris@87 4060 [7 -- 9]]
Chris@87 4061 >>> print x.ravel()
Chris@87 4062 [1 -- 3 -- 5 -- 7 -- 9]
Chris@87 4063
Chris@87 4064 """
Chris@87 4065 r = ndarray.ravel(self._data).view(type(self))
Chris@87 4066 r._update_from(self)
Chris@87 4067 if self._mask is not nomask:
Chris@87 4068 r._mask = ndarray.ravel(self._mask).reshape(r.shape)
Chris@87 4069 else:
Chris@87 4070 r._mask = nomask
Chris@87 4071 return r
Chris@87 4072 #
Chris@87 4073 repeat = _arraymethod('repeat')
Chris@87 4074 #
Chris@87 4075 def reshape (self, *s, **kwargs):
Chris@87 4076 """
Chris@87 4077 Give a new shape to the array without changing its data.
Chris@87 4078
Chris@87 4079 Returns a masked array containing the same data, but with a new shape.
Chris@87 4080 The result is a view on the original array; if this is not possible, a
Chris@87 4081 ValueError is raised.
Chris@87 4082
Chris@87 4083 Parameters
Chris@87 4084 ----------
Chris@87 4085 shape : int or tuple of ints
Chris@87 4086 The new shape should be compatible with the original shape. If an
Chris@87 4087 integer is supplied, then the result will be a 1-D array of that
Chris@87 4088 length.
Chris@87 4089 order : {'C', 'F'}, optional
Chris@87 4090 Determines whether the array data should be viewed as in C
Chris@87 4091 (row-major) or FORTRAN (column-major) order.
Chris@87 4092
Chris@87 4093 Returns
Chris@87 4094 -------
Chris@87 4095 reshaped_array : array
Chris@87 4096 A new view on the array.
Chris@87 4097
Chris@87 4098 See Also
Chris@87 4099 --------
Chris@87 4100 reshape : Equivalent function in the masked array module.
Chris@87 4101 numpy.ndarray.reshape : Equivalent method on ndarray object.
Chris@87 4102 numpy.reshape : Equivalent function in the NumPy module.
Chris@87 4103
Chris@87 4104 Notes
Chris@87 4105 -----
Chris@87 4106 The reshaping operation cannot guarantee that a copy will not be made,
Chris@87 4107 to modify the shape in place, use ``a.shape = s``
Chris@87 4108
Chris@87 4109 Examples
Chris@87 4110 --------
Chris@87 4111 >>> x = np.ma.array([[1,2],[3,4]], mask=[1,0,0,1])
Chris@87 4112 >>> print x
Chris@87 4113 [[-- 2]
Chris@87 4114 [3 --]]
Chris@87 4115 >>> x = x.reshape((4,1))
Chris@87 4116 >>> print x
Chris@87 4117 [[--]
Chris@87 4118 [2]
Chris@87 4119 [3]
Chris@87 4120 [--]]
Chris@87 4121
Chris@87 4122 """
Chris@87 4123 kwargs.update(order=kwargs.get('order', 'C'))
Chris@87 4124 result = self._data.reshape(*s, **kwargs).view(type(self))
Chris@87 4125 result._update_from(self)
Chris@87 4126 mask = self._mask
Chris@87 4127 if mask is not nomask:
Chris@87 4128 result._mask = mask.reshape(*s, **kwargs)
Chris@87 4129 return result
Chris@87 4130 #
Chris@87 4131 def resize(self, newshape, refcheck=True, order=False):
Chris@87 4132 """
Chris@87 4133 .. warning::
Chris@87 4134
Chris@87 4135 This method does nothing, except raise a ValueError exception. A
Chris@87 4136 masked array does not own its data and therefore cannot safely be
Chris@87 4137 resized in place. Use the `numpy.ma.resize` function instead.
Chris@87 4138
Chris@87 4139 This method is difficult to implement safely and may be deprecated in
Chris@87 4140 future releases of NumPy.
Chris@87 4141
Chris@87 4142 """
Chris@87 4143 # Note : the 'order' keyword looks broken, let's just drop it
Chris@87 4144 # try:
Chris@87 4145 # ndarray.resize(self, newshape, refcheck=refcheck)
Chris@87 4146 # if self.mask is not nomask:
Chris@87 4147 # self._mask.resize(newshape, refcheck=refcheck)
Chris@87 4148 # except ValueError:
Chris@87 4149 # raise ValueError("Cannot resize an array that has been referenced "
Chris@87 4150 # "or is referencing another array in this way.\n"
Chris@87 4151 # "Use the numpy.ma.resize function.")
Chris@87 4152 # return None
Chris@87 4153 errmsg = "A masked array does not own its data "\
Chris@87 4154 "and therefore cannot be resized.\n" \
Chris@87 4155 "Use the numpy.ma.resize function instead."
Chris@87 4156 raise ValueError(errmsg)
Chris@87 4157 #
Chris@87 4158 def put(self, indices, values, mode='raise'):
Chris@87 4159 """
Chris@87 4160 Set storage-indexed locations to corresponding values.
Chris@87 4161
Chris@87 4162 Sets self._data.flat[n] = values[n] for each n in indices.
Chris@87 4163 If `values` is shorter than `indices` then it will repeat.
Chris@87 4164 If `values` has some masked values, the initial mask is updated
Chris@87 4165 in consequence, else the corresponding values are unmasked.
Chris@87 4166
Chris@87 4167 Parameters
Chris@87 4168 ----------
Chris@87 4169 indices : 1-D array_like
Chris@87 4170 Target indices, interpreted as integers.
Chris@87 4171 values : array_like
Chris@87 4172 Values to place in self._data copy at target indices.
Chris@87 4173 mode : {'raise', 'wrap', 'clip'}, optional
Chris@87 4174 Specifies how out-of-bounds indices will behave.
Chris@87 4175 'raise' : raise an error.
Chris@87 4176 'wrap' : wrap around.
Chris@87 4177 'clip' : clip to the range.
Chris@87 4178
Chris@87 4179 Notes
Chris@87 4180 -----
Chris@87 4181 `values` can be a scalar or length 1 array.
Chris@87 4182
Chris@87 4183 Examples
Chris@87 4184 --------
Chris@87 4185 >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
Chris@87 4186 >>> print x
Chris@87 4187 [[1 -- 3]
Chris@87 4188 [-- 5 --]
Chris@87 4189 [7 -- 9]]
Chris@87 4190 >>> x.put([0,4,8],[10,20,30])
Chris@87 4191 >>> print x
Chris@87 4192 [[10 -- 3]
Chris@87 4193 [-- 20 --]
Chris@87 4194 [7 -- 30]]
Chris@87 4195
Chris@87 4196 >>> x.put(4,999)
Chris@87 4197 >>> print x
Chris@87 4198 [[10 -- 3]
Chris@87 4199 [-- 999 --]
Chris@87 4200 [7 -- 30]]
Chris@87 4201
Chris@87 4202 """
Chris@87 4203 m = self._mask
Chris@87 4204 # Hard mask: Get rid of the values/indices that fall on masked data
Chris@87 4205 if self._hardmask and self._mask is not nomask:
Chris@87 4206 mask = self._mask[indices]
Chris@87 4207 indices = narray(indices, copy=False)
Chris@87 4208 values = narray(values, copy=False, subok=True)
Chris@87 4209 values.resize(indices.shape)
Chris@87 4210 indices = indices[~mask]
Chris@87 4211 values = values[~mask]
Chris@87 4212 #....
Chris@87 4213 self._data.put(indices, values, mode=mode)
Chris@87 4214 #....
Chris@87 4215 if m is nomask:
Chris@87 4216 m = getmask(values)
Chris@87 4217 else:
Chris@87 4218 m = m.copy()
Chris@87 4219 if getmask(values) is nomask:
Chris@87 4220 m.put(indices, False, mode=mode)
Chris@87 4221 else:
Chris@87 4222 m.put(indices, values._mask, mode=mode)
Chris@87 4223 m = make_mask(m, copy=False, shrink=True)
Chris@87 4224 self._mask = m
Chris@87 4225 #............................................
Chris@87 4226 def ids (self):
Chris@87 4227 """
Chris@87 4228 Return the addresses of the data and mask areas.
Chris@87 4229
Chris@87 4230 Parameters
Chris@87 4231 ----------
Chris@87 4232 None
Chris@87 4233
Chris@87 4234 Examples
Chris@87 4235 --------
Chris@87 4236 >>> x = np.ma.array([1, 2, 3], mask=[0, 1, 1])
Chris@87 4237 >>> x.ids()
Chris@87 4238 (166670640, 166659832)
Chris@87 4239
Chris@87 4240 If the array has no mask, the address of `nomask` is returned. This address
Chris@87 4241 is typically not close to the data in memory:
Chris@87 4242
Chris@87 4243 >>> x = np.ma.array([1, 2, 3])
Chris@87 4244 >>> x.ids()
Chris@87 4245 (166691080, 3083169284L)
Chris@87 4246
Chris@87 4247 """
Chris@87 4248 if self._mask is nomask:
Chris@87 4249 return (self.ctypes.data, id(nomask))
Chris@87 4250 return (self.ctypes.data, self._mask.ctypes.data)
Chris@87 4251
Chris@87 4252 def iscontiguous(self):
Chris@87 4253 """
Chris@87 4254 Return a boolean indicating whether the data is contiguous.
Chris@87 4255
Chris@87 4256 Parameters
Chris@87 4257 ----------
Chris@87 4258 None
Chris@87 4259
Chris@87 4260 Examples
Chris@87 4261 --------
Chris@87 4262 >>> x = np.ma.array([1, 2, 3])
Chris@87 4263 >>> x.iscontiguous()
Chris@87 4264 True
Chris@87 4265
Chris@87 4266 `iscontiguous` returns one of the flags of the masked array:
Chris@87 4267
Chris@87 4268 >>> x.flags
Chris@87 4269 C_CONTIGUOUS : True
Chris@87 4270 F_CONTIGUOUS : True
Chris@87 4271 OWNDATA : False
Chris@87 4272 WRITEABLE : True
Chris@87 4273 ALIGNED : True
Chris@87 4274 UPDATEIFCOPY : False
Chris@87 4275
Chris@87 4276 """
Chris@87 4277 return self.flags['CONTIGUOUS']
Chris@87 4278
Chris@87 4279 #............................................
Chris@87 4280 def all(self, axis=None, out=None):
Chris@87 4281 """
Chris@87 4282 Check if all of the elements of `a` are true.
Chris@87 4283
Chris@87 4284 Performs a :func:`logical_and` over the given axis and returns the result.
Chris@87 4285 Masked values are considered as True during computation.
Chris@87 4286 For convenience, the output array is masked where ALL the values along the
Chris@87 4287 current axis are masked: if the output would have been a scalar and that
Chris@87 4288 all the values are masked, then the output is `masked`.
Chris@87 4289
Chris@87 4290 Parameters
Chris@87 4291 ----------
Chris@87 4292 axis : {None, integer}
Chris@87 4293 Axis to perform the operation over.
Chris@87 4294 If None, perform over flattened array.
Chris@87 4295 out : {None, array}, optional
Chris@87 4296 Array into which the result can be placed. Its type is preserved
Chris@87 4297 and it must be of the right shape to hold the output.
Chris@87 4298
Chris@87 4299 See Also
Chris@87 4300 --------
Chris@87 4301 all : equivalent function
Chris@87 4302
Chris@87 4303 Examples
Chris@87 4304 --------
Chris@87 4305 >>> np.ma.array([1,2,3]).all()
Chris@87 4306 True
Chris@87 4307 >>> a = np.ma.array([1,2,3], mask=True)
Chris@87 4308 >>> (a.all() is np.ma.masked)
Chris@87 4309 True
Chris@87 4310
Chris@87 4311 """
Chris@87 4312 mask = _check_mask_axis(self._mask, axis)
Chris@87 4313 if out is None:
Chris@87 4314 d = self.filled(True).all(axis=axis).view(type(self))
Chris@87 4315 if d.ndim:
Chris@87 4316 d.__setmask__(mask)
Chris@87 4317 elif mask:
Chris@87 4318 return masked
Chris@87 4319 return d
Chris@87 4320 self.filled(True).all(axis=axis, out=out)
Chris@87 4321 if isinstance(out, MaskedArray):
Chris@87 4322 if out.ndim or mask:
Chris@87 4323 out.__setmask__(mask)
Chris@87 4324 return out
Chris@87 4325
Chris@87 4326
Chris@87 4327 def any(self, axis=None, out=None):
Chris@87 4328 """
Chris@87 4329 Check if any of the elements of `a` are true.
Chris@87 4330
Chris@87 4331 Performs a logical_or over the given axis and returns the result.
Chris@87 4332 Masked values are considered as False during computation.
Chris@87 4333
Chris@87 4334 Parameters
Chris@87 4335 ----------
Chris@87 4336 axis : {None, integer}
Chris@87 4337 Axis to perform the operation over.
Chris@87 4338 If None, perform over flattened array and return a scalar.
Chris@87 4339 out : {None, array}, optional
Chris@87 4340 Array into which the result can be placed. Its type is preserved
Chris@87 4341 and it must be of the right shape to hold the output.
Chris@87 4342
Chris@87 4343 See Also
Chris@87 4344 --------
Chris@87 4345 any : equivalent function
Chris@87 4346
Chris@87 4347 """
Chris@87 4348 mask = _check_mask_axis(self._mask, axis)
Chris@87 4349 if out is None:
Chris@87 4350 d = self.filled(False).any(axis=axis).view(type(self))
Chris@87 4351 if d.ndim:
Chris@87 4352 d.__setmask__(mask)
Chris@87 4353 elif mask:
Chris@87 4354 d = masked
Chris@87 4355 return d
Chris@87 4356 self.filled(False).any(axis=axis, out=out)
Chris@87 4357 if isinstance(out, MaskedArray):
Chris@87 4358 if out.ndim or mask:
Chris@87 4359 out.__setmask__(mask)
Chris@87 4360 return out
Chris@87 4361
Chris@87 4362
Chris@87 4363 def nonzero(self):
Chris@87 4364 """
Chris@87 4365 Return the indices of unmasked elements that are not zero.
Chris@87 4366
Chris@87 4367 Returns a tuple of arrays, one for each dimension, containing the
Chris@87 4368 indices of the non-zero elements in that dimension. The corresponding
Chris@87 4369 non-zero values can be obtained with::
Chris@87 4370
Chris@87 4371 a[a.nonzero()]
Chris@87 4372
Chris@87 4373 To group the indices by element, rather than dimension, use
Chris@87 4374 instead::
Chris@87 4375
Chris@87 4376 np.transpose(a.nonzero())
Chris@87 4377
Chris@87 4378 The result of this is always a 2d array, with a row for each non-zero
Chris@87 4379 element.
Chris@87 4380
Chris@87 4381 Parameters
Chris@87 4382 ----------
Chris@87 4383 None
Chris@87 4384
Chris@87 4385 Returns
Chris@87 4386 -------
Chris@87 4387 tuple_of_arrays : tuple
Chris@87 4388 Indices of elements that are non-zero.
Chris@87 4389
Chris@87 4390 See Also
Chris@87 4391 --------
Chris@87 4392 numpy.nonzero :
Chris@87 4393 Function operating on ndarrays.
Chris@87 4394 flatnonzero :
Chris@87 4395 Return indices that are non-zero in the flattened version of the input
Chris@87 4396 array.
Chris@87 4397 ndarray.nonzero :
Chris@87 4398 Equivalent ndarray method.
Chris@87 4399 count_nonzero :
Chris@87 4400 Counts the number of non-zero elements in the input array.
Chris@87 4401
Chris@87 4402 Examples
Chris@87 4403 --------
Chris@87 4404 >>> import numpy.ma as ma
Chris@87 4405 >>> x = ma.array(np.eye(3))
Chris@87 4406 >>> x
Chris@87 4407 masked_array(data =
Chris@87 4408 [[ 1. 0. 0.]
Chris@87 4409 [ 0. 1. 0.]
Chris@87 4410 [ 0. 0. 1.]],
Chris@87 4411 mask =
Chris@87 4412 False,
Chris@87 4413 fill_value=1e+20)
Chris@87 4414 >>> x.nonzero()
Chris@87 4415 (array([0, 1, 2]), array([0, 1, 2]))
Chris@87 4416
Chris@87 4417 Masked elements are ignored.
Chris@87 4418
Chris@87 4419 >>> x[1, 1] = ma.masked
Chris@87 4420 >>> x
Chris@87 4421 masked_array(data =
Chris@87 4422 [[1.0 0.0 0.0]
Chris@87 4423 [0.0 -- 0.0]
Chris@87 4424 [0.0 0.0 1.0]],
Chris@87 4425 mask =
Chris@87 4426 [[False False False]
Chris@87 4427 [False True False]
Chris@87 4428 [False False False]],
Chris@87 4429 fill_value=1e+20)
Chris@87 4430 >>> x.nonzero()
Chris@87 4431 (array([0, 2]), array([0, 2]))
Chris@87 4432
Chris@87 4433 Indices can also be grouped by element.
Chris@87 4434
Chris@87 4435 >>> np.transpose(x.nonzero())
Chris@87 4436 array([[0, 0],
Chris@87 4437 [2, 2]])
Chris@87 4438
Chris@87 4439 A common use for ``nonzero`` is to find the indices of an array, where
Chris@87 4440 a condition is True. Given an array `a`, the condition `a` > 3 is a
Chris@87 4441 boolean array and since False is interpreted as 0, ma.nonzero(a > 3)
Chris@87 4442 yields the indices of the `a` where the condition is true.
Chris@87 4443
Chris@87 4444 >>> a = ma.array([[1,2,3],[4,5,6],[7,8,9]])
Chris@87 4445 >>> a > 3
Chris@87 4446 masked_array(data =
Chris@87 4447 [[False False False]
Chris@87 4448 [ True True True]
Chris@87 4449 [ True True True]],
Chris@87 4450 mask =
Chris@87 4451 False,
Chris@87 4452 fill_value=999999)
Chris@87 4453 >>> ma.nonzero(a > 3)
Chris@87 4454 (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))
Chris@87 4455
Chris@87 4456 The ``nonzero`` method of the condition array can also be called.
Chris@87 4457
Chris@87 4458 >>> (a > 3).nonzero()
Chris@87 4459 (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))
Chris@87 4460
Chris@87 4461 """
Chris@87 4462 return narray(self.filled(0), copy=False).nonzero()
Chris@87 4463
Chris@87 4464
Chris@87 4465 def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None):
Chris@87 4466 """
Chris@87 4467 (this docstring should be overwritten)
Chris@87 4468 """
Chris@87 4469 #!!!: implement out + test!
Chris@87 4470 m = self._mask
Chris@87 4471 if m is nomask:
Chris@87 4472 result = super(MaskedArray, self).trace(offset=offset, axis1=axis1,
Chris@87 4473 axis2=axis2, out=out)
Chris@87 4474 return result.astype(dtype)
Chris@87 4475 else:
Chris@87 4476 D = self.diagonal(offset=offset, axis1=axis1, axis2=axis2)
Chris@87 4477 return D.astype(dtype).filled(0).sum(axis=None, out=out)
Chris@87 4478 trace.__doc__ = ndarray.trace.__doc__
Chris@87 4479
Chris@87 4480 def sum(self, axis=None, dtype=None, out=None):
Chris@87 4481 """
Chris@87 4482 Return the sum of the array elements over the given axis.
Chris@87 4483 Masked elements are set to 0 internally.
Chris@87 4484
Chris@87 4485 Parameters
Chris@87 4486 ----------
Chris@87 4487 axis : {None, -1, int}, optional
Chris@87 4488 Axis along which the sum is computed. The default
Chris@87 4489 (`axis` = None) is to compute over the flattened array.
Chris@87 4490 dtype : {None, dtype}, optional
Chris@87 4491 Determines the type of the returned array and of the accumulator
Chris@87 4492 where the elements are summed. If dtype has the value None and
Chris@87 4493 the type of a is an integer type of precision less than the default
Chris@87 4494 platform integer, then the default platform integer precision is
Chris@87 4495 used. Otherwise, the dtype is the same as that of a.
Chris@87 4496 out : {None, ndarray}, optional
Chris@87 4497 Alternative output array in which to place the result. It must
Chris@87 4498 have the same shape and buffer length as the expected output
Chris@87 4499 but the type will be cast if necessary.
Chris@87 4500
Chris@87 4501 Returns
Chris@87 4502 -------
Chris@87 4503 sum_along_axis : MaskedArray or scalar
Chris@87 4504 An array with the same shape as self, with the specified
Chris@87 4505 axis removed. If self is a 0-d array, or if `axis` is None, a scalar
Chris@87 4506 is returned. If an output array is specified, a reference to
Chris@87 4507 `out` is returned.
Chris@87 4508
Chris@87 4509 Examples
Chris@87 4510 --------
Chris@87 4511 >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
Chris@87 4512 >>> print x
Chris@87 4513 [[1 -- 3]
Chris@87 4514 [-- 5 --]
Chris@87 4515 [7 -- 9]]
Chris@87 4516 >>> print x.sum()
Chris@87 4517 25
Chris@87 4518 >>> print x.sum(axis=1)
Chris@87 4519 [4 5 16]
Chris@87 4520 >>> print x.sum(axis=0)
Chris@87 4521 [8 5 12]
Chris@87 4522 >>> print type(x.sum(axis=0, dtype=np.int64)[0])
Chris@87 4523 <type 'numpy.int64'>
Chris@87 4524
Chris@87 4525 """
Chris@87 4526 _mask = ndarray.__getattribute__(self, '_mask')
Chris@87 4527 newmask = _check_mask_axis(_mask, axis)
Chris@87 4528 # No explicit output
Chris@87 4529 if out is None:
Chris@87 4530 result = self.filled(0).sum(axis, dtype=dtype)
Chris@87 4531 rndim = getattr(result, 'ndim', 0)
Chris@87 4532 if rndim:
Chris@87 4533 result = result.view(type(self))
Chris@87 4534 result.__setmask__(newmask)
Chris@87 4535 elif newmask:
Chris@87 4536 result = masked
Chris@87 4537 return result
Chris@87 4538 # Explicit output
Chris@87 4539 result = self.filled(0).sum(axis, dtype=dtype, out=out)
Chris@87 4540 if isinstance(out, MaskedArray):
Chris@87 4541 outmask = getattr(out, '_mask', nomask)
Chris@87 4542 if (outmask is nomask):
Chris@87 4543 outmask = out._mask = make_mask_none(out.shape)
Chris@87 4544 outmask.flat = newmask
Chris@87 4545 return out
Chris@87 4546
Chris@87 4547
Chris@87 4548 def cumsum(self, axis=None, dtype=None, out=None):
Chris@87 4549 """
Chris@87 4550 Return the cumulative sum of the elements along the given axis.
Chris@87 4551 The cumulative sum is calculated over the flattened array by
Chris@87 4552 default, otherwise over the specified axis.
Chris@87 4553
Chris@87 4554 Masked values are set to 0 internally during the computation.
Chris@87 4555 However, their position is saved, and the result will be masked at
Chris@87 4556 the same locations.
Chris@87 4557
Chris@87 4558 Parameters
Chris@87 4559 ----------
Chris@87 4560 axis : {None, -1, int}, optional
Chris@87 4561 Axis along which the sum is computed. The default (`axis` = None) is to
Chris@87 4562 compute over the flattened array. `axis` may be negative, in which case
Chris@87 4563 it counts from the last to the first axis.
Chris@87 4564 dtype : {None, dtype}, optional
Chris@87 4565 Type of the returned array and of the accumulator in which the
Chris@87 4566 elements are summed. If `dtype` is not specified, it defaults
Chris@87 4567 to the dtype of `a`, unless `a` has an integer dtype with a
Chris@87 4568 precision less than that of the default platform integer. In
Chris@87 4569 that case, the default platform integer is used.
Chris@87 4570 out : ndarray, optional
Chris@87 4571 Alternative output array in which to place the result. It must
Chris@87 4572 have the same shape and buffer length as the expected output
Chris@87 4573 but the type will be cast if necessary.
Chris@87 4574
Chris@87 4575 Returns
Chris@87 4576 -------
Chris@87 4577 cumsum : ndarray.
Chris@87 4578 A new array holding the result is returned unless ``out`` is
Chris@87 4579 specified, in which case a reference to ``out`` is returned.
Chris@87 4580
Chris@87 4581 Notes
Chris@87 4582 -----
Chris@87 4583 The mask is lost if `out` is not a valid :class:`MaskedArray` !
Chris@87 4584
Chris@87 4585 Arithmetic is modular when using integer types, and no error is
Chris@87 4586 raised on overflow.
Chris@87 4587
Chris@87 4588 Examples
Chris@87 4589 --------
Chris@87 4590 >>> marr = np.ma.array(np.arange(10), mask=[0,0,0,1,1,1,0,0,0,0])
Chris@87 4591 >>> print marr.cumsum()
Chris@87 4592 [0 1 3 -- -- -- 9 16 24 33]
Chris@87 4593
Chris@87 4594 """
Chris@87 4595 result = self.filled(0).cumsum(axis=axis, dtype=dtype, out=out)
Chris@87 4596 if out is not None:
Chris@87 4597 if isinstance(out, MaskedArray):
Chris@87 4598 out.__setmask__(self.mask)
Chris@87 4599 return out
Chris@87 4600 result = result.view(type(self))
Chris@87 4601 result.__setmask__(self._mask)
Chris@87 4602 return result
Chris@87 4603
Chris@87 4604
Chris@87 4605 def prod(self, axis=None, dtype=None, out=None):
Chris@87 4606 """
Chris@87 4607 Return the product of the array elements over the given axis.
Chris@87 4608 Masked elements are set to 1 internally for computation.
Chris@87 4609
Chris@87 4610 Parameters
Chris@87 4611 ----------
Chris@87 4612 axis : {None, int}, optional
Chris@87 4613 Axis over which the product is taken. If None is used, then the
Chris@87 4614 product is over all the array elements.
Chris@87 4615 dtype : {None, dtype}, optional
Chris@87 4616 Determines the type of the returned array and of the accumulator
Chris@87 4617 where the elements are multiplied. If ``dtype`` has the value ``None``
Chris@87 4618 and the type of a is an integer type of precision less than the default
Chris@87 4619 platform integer, then the default platform integer precision is
Chris@87 4620 used. Otherwise, the dtype is the same as that of a.
Chris@87 4621 out : {None, array}, optional
Chris@87 4622 Alternative output array in which to place the result. It must have
Chris@87 4623 the same shape as the expected output but the type will be cast if
Chris@87 4624 necessary.
Chris@87 4625
Chris@87 4626 Returns
Chris@87 4627 -------
Chris@87 4628 product_along_axis : {array, scalar}, see dtype parameter above.
Chris@87 4629 Returns an array whose shape is the same as a with the specified
Chris@87 4630 axis removed. Returns a 0d array when a is 1d or axis=None.
Chris@87 4631 Returns a reference to the specified output array if specified.
Chris@87 4632
Chris@87 4633 See Also
Chris@87 4634 --------
Chris@87 4635 prod : equivalent function
Chris@87 4636
Chris@87 4637 Notes
Chris@87 4638 -----
Chris@87 4639 Arithmetic is modular when using integer types, and no error is raised
Chris@87 4640 on overflow.
Chris@87 4641
Chris@87 4642 Examples
Chris@87 4643 --------
Chris@87 4644 >>> np.prod([1.,2.])
Chris@87 4645 2.0
Chris@87 4646 >>> np.prod([1.,2.], dtype=np.int32)
Chris@87 4647 2
Chris@87 4648 >>> np.prod([[1.,2.],[3.,4.]])
Chris@87 4649 24.0
Chris@87 4650 >>> np.prod([[1.,2.],[3.,4.]], axis=1)
Chris@87 4651 array([ 2., 12.])
Chris@87 4652
Chris@87 4653 """
Chris@87 4654 _mask = ndarray.__getattribute__(self, '_mask')
Chris@87 4655 newmask = _check_mask_axis(_mask, axis)
Chris@87 4656 # No explicit output
Chris@87 4657 if out is None:
Chris@87 4658 result = self.filled(1).prod(axis, dtype=dtype)
Chris@87 4659 rndim = getattr(result, 'ndim', 0)
Chris@87 4660 if rndim:
Chris@87 4661 result = result.view(type(self))
Chris@87 4662 result.__setmask__(newmask)
Chris@87 4663 elif newmask:
Chris@87 4664 result = masked
Chris@87 4665 return result
Chris@87 4666 # Explicit output
Chris@87 4667 result = self.filled(1).prod(axis, dtype=dtype, out=out)
Chris@87 4668 if isinstance(out, MaskedArray):
Chris@87 4669 outmask = getattr(out, '_mask', nomask)
Chris@87 4670 if (outmask is nomask):
Chris@87 4671 outmask = out._mask = make_mask_none(out.shape)
Chris@87 4672 outmask.flat = newmask
Chris@87 4673 return out
Chris@87 4674
Chris@87 4675 product = prod
Chris@87 4676
Chris@87 4677 def cumprod(self, axis=None, dtype=None, out=None):
Chris@87 4678 """
Chris@87 4679 Return the cumulative product of the elements along the given axis.
Chris@87 4680 The cumulative product is taken over the flattened array by
Chris@87 4681 default, otherwise over the specified axis.
Chris@87 4682
Chris@87 4683 Masked values are set to 1 internally during the computation.
Chris@87 4684 However, their position is saved, and the result will be masked at
Chris@87 4685 the same locations.
Chris@87 4686
Chris@87 4687 Parameters
Chris@87 4688 ----------
Chris@87 4689 axis : {None, -1, int}, optional
Chris@87 4690 Axis along which the product is computed. The default
Chris@87 4691 (`axis` = None) is to compute over the flattened array.
Chris@87 4692 dtype : {None, dtype}, optional
Chris@87 4693 Determines the type of the returned array and of the accumulator
Chris@87 4694 where the elements are multiplied. If ``dtype`` has the value ``None``
Chris@87 4695 and the type of ``a`` is an integer type of precision less than the
Chris@87 4696 default platform integer, then the default platform integer precision
Chris@87 4697 is used. Otherwise, the dtype is the same as that of ``a``.
Chris@87 4698 out : ndarray, optional
Chris@87 4699 Alternative output array in which to place the result. It must
Chris@87 4700 have the same shape and buffer length as the expected output
Chris@87 4701 but the type will be cast if necessary.
Chris@87 4702
Chris@87 4703 Returns
Chris@87 4704 -------
Chris@87 4705 cumprod : ndarray
Chris@87 4706 A new array holding the result is returned unless out is specified,
Chris@87 4707 in which case a reference to out is returned.
Chris@87 4708
Chris@87 4709 Notes
Chris@87 4710 -----
Chris@87 4711 The mask is lost if `out` is not a valid MaskedArray !
Chris@87 4712
Chris@87 4713 Arithmetic is modular when using integer types, and no error is
Chris@87 4714 raised on overflow.
Chris@87 4715
Chris@87 4716 """
Chris@87 4717 result = self.filled(1).cumprod(axis=axis, dtype=dtype, out=out)
Chris@87 4718 if out is not None:
Chris@87 4719 if isinstance(out, MaskedArray):
Chris@87 4720 out.__setmask__(self._mask)
Chris@87 4721 return out
Chris@87 4722 result = result.view(type(self))
Chris@87 4723 result.__setmask__(self._mask)
Chris@87 4724 return result
Chris@87 4725
Chris@87 4726
Chris@87 4727 def mean(self, axis=None, dtype=None, out=None):
Chris@87 4728 """
Chris@87 4729 Returns the average of the array elements.
Chris@87 4730
Chris@87 4731 Masked entries are ignored.
Chris@87 4732 The average is taken over the flattened array by default, otherwise over
Chris@87 4733 the specified axis. Refer to `numpy.mean` for the full documentation.
Chris@87 4734
Chris@87 4735 Parameters
Chris@87 4736 ----------
Chris@87 4737 a : array_like
Chris@87 4738 Array containing numbers whose mean is desired. If `a` is not an
Chris@87 4739 array, a conversion is attempted.
Chris@87 4740 axis : int, optional
Chris@87 4741 Axis along which the means are computed. The default is to compute
Chris@87 4742 the mean of the flattened array.
Chris@87 4743 dtype : dtype, optional
Chris@87 4744 Type to use in computing the mean. For integer inputs, the default
Chris@87 4745 is float64; for floating point, inputs it is the same as the input
Chris@87 4746 dtype.
Chris@87 4747 out : ndarray, optional
Chris@87 4748 Alternative output array in which to place the result. It must have
Chris@87 4749 the same shape as the expected output but the type will be cast if
Chris@87 4750 necessary.
Chris@87 4751
Chris@87 4752 Returns
Chris@87 4753 -------
Chris@87 4754 mean : ndarray, see dtype parameter above
Chris@87 4755 If `out=None`, returns a new array containing the mean values,
Chris@87 4756 otherwise a reference to the output array is returned.
Chris@87 4757
Chris@87 4758 See Also
Chris@87 4759 --------
Chris@87 4760 numpy.ma.mean : Equivalent function.
Chris@87 4761 numpy.mean : Equivalent function on non-masked arrays.
Chris@87 4762 numpy.ma.average: Weighted average.
Chris@87 4763
Chris@87 4764 Examples
Chris@87 4765 --------
Chris@87 4766 >>> a = np.ma.array([1,2,3], mask=[False, False, True])
Chris@87 4767 >>> a
Chris@87 4768 masked_array(data = [1 2 --],
Chris@87 4769 mask = [False False True],
Chris@87 4770 fill_value = 999999)
Chris@87 4771 >>> a.mean()
Chris@87 4772 1.5
Chris@87 4773
Chris@87 4774 """
Chris@87 4775 if self._mask is nomask:
Chris@87 4776 result = super(MaskedArray, self).mean(axis=axis, dtype=dtype)
Chris@87 4777 else:
Chris@87 4778 dsum = self.sum(axis=axis, dtype=dtype)
Chris@87 4779 cnt = self.count(axis=axis)
Chris@87 4780 if cnt.shape == () and (cnt == 0):
Chris@87 4781 result = masked
Chris@87 4782 else:
Chris@87 4783 result = dsum * 1. / cnt
Chris@87 4784 if out is not None:
Chris@87 4785 out.flat = result
Chris@87 4786 if isinstance(out, MaskedArray):
Chris@87 4787 outmask = getattr(out, '_mask', nomask)
Chris@87 4788 if (outmask is nomask):
Chris@87 4789 outmask = out._mask = make_mask_none(out.shape)
Chris@87 4790 outmask.flat = getattr(result, '_mask', nomask)
Chris@87 4791 return out
Chris@87 4792 return result
Chris@87 4793
Chris@87 4794 def anom(self, axis=None, dtype=None):
Chris@87 4795 """
Chris@87 4796 Compute the anomalies (deviations from the arithmetic mean)
Chris@87 4797 along the given axis.
Chris@87 4798
Chris@87 4799 Returns an array of anomalies, with the same shape as the input and
Chris@87 4800 where the arithmetic mean is computed along the given axis.
Chris@87 4801
Chris@87 4802 Parameters
Chris@87 4803 ----------
Chris@87 4804 axis : int, optional
Chris@87 4805 Axis over which the anomalies are taken.
Chris@87 4806 The default is to use the mean of the flattened array as reference.
Chris@87 4807 dtype : dtype, optional
Chris@87 4808 Type to use in computing the variance. For arrays of integer type
Chris@87 4809 the default is float32; for arrays of float types it is the same as
Chris@87 4810 the array type.
Chris@87 4811
Chris@87 4812 See Also
Chris@87 4813 --------
Chris@87 4814 mean : Compute the mean of the array.
Chris@87 4815
Chris@87 4816 Examples
Chris@87 4817 --------
Chris@87 4818 >>> a = np.ma.array([1,2,3])
Chris@87 4819 >>> a.anom()
Chris@87 4820 masked_array(data = [-1. 0. 1.],
Chris@87 4821 mask = False,
Chris@87 4822 fill_value = 1e+20)
Chris@87 4823
Chris@87 4824 """
Chris@87 4825 m = self.mean(axis, dtype)
Chris@87 4826 if not axis:
Chris@87 4827 return (self - m)
Chris@87 4828 else:
Chris@87 4829 return (self - expand_dims(m, axis))
Chris@87 4830
Chris@87 4831 def var(self, axis=None, dtype=None, out=None, ddof=0):
Chris@87 4832 ""
Chris@87 4833 # Easy case: nomask, business as usual
Chris@87 4834 if self._mask is nomask:
Chris@87 4835 return self._data.var(axis=axis, dtype=dtype, out=out, ddof=ddof)
Chris@87 4836 # Some data are masked, yay!
Chris@87 4837 cnt = self.count(axis=axis) - ddof
Chris@87 4838 danom = self.anom(axis=axis, dtype=dtype)
Chris@87 4839 if iscomplexobj(self):
Chris@87 4840 danom = umath.absolute(danom) ** 2
Chris@87 4841 else:
Chris@87 4842 danom *= danom
Chris@87 4843 dvar = divide(danom.sum(axis), cnt).view(type(self))
Chris@87 4844 # Apply the mask if it's not a scalar
Chris@87 4845 if dvar.ndim:
Chris@87 4846 dvar._mask = mask_or(self._mask.all(axis), (cnt <= 0))
Chris@87 4847 dvar._update_from(self)
Chris@87 4848 elif getattr(dvar, '_mask', False):
Chris@87 4849 # Make sure that masked is returned when the scalar is masked.
Chris@87 4850 dvar = masked
Chris@87 4851 if out is not None:
Chris@87 4852 if isinstance(out, MaskedArray):
Chris@87 4853 out.flat = 0
Chris@87 4854 out.__setmask__(True)
Chris@87 4855 elif out.dtype.kind in 'biu':
Chris@87 4856 errmsg = "Masked data information would be lost in one or "\
Chris@87 4857 "more location."
Chris@87 4858 raise MaskError(errmsg)
Chris@87 4859 else:
Chris@87 4860 out.flat = np.nan
Chris@87 4861 return out
Chris@87 4862 # In case with have an explicit output
Chris@87 4863 if out is not None:
Chris@87 4864 # Set the data
Chris@87 4865 out.flat = dvar
Chris@87 4866 # Set the mask if needed
Chris@87 4867 if isinstance(out, MaskedArray):
Chris@87 4868 out.__setmask__(dvar.mask)
Chris@87 4869 return out
Chris@87 4870 return dvar
Chris@87 4871 var.__doc__ = np.var.__doc__
Chris@87 4872
Chris@87 4873
Chris@87 4874 def std(self, axis=None, dtype=None, out=None, ddof=0):
Chris@87 4875 ""
Chris@87 4876 dvar = self.var(axis=axis, dtype=dtype, out=out, ddof=ddof)
Chris@87 4877 if dvar is not masked:
Chris@87 4878 if out is not None:
Chris@87 4879 np.power(out, 0.5, out=out, casting='unsafe')
Chris@87 4880 return out
Chris@87 4881 dvar = sqrt(dvar)
Chris@87 4882 return dvar
Chris@87 4883 std.__doc__ = np.std.__doc__
Chris@87 4884
Chris@87 4885 #............................................
Chris@87 4886 def round(self, decimals=0, out=None):
Chris@87 4887 """
Chris@87 4888 Return an array rounded a to the given number of decimals.
Chris@87 4889
Chris@87 4890 Refer to `numpy.around` for full documentation.
Chris@87 4891
Chris@87 4892 See Also
Chris@87 4893 --------
Chris@87 4894 numpy.around : equivalent function
Chris@87 4895
Chris@87 4896 """
Chris@87 4897 result = self._data.round(decimals=decimals, out=out).view(type(self))
Chris@87 4898 result._mask = self._mask
Chris@87 4899 result._update_from(self)
Chris@87 4900 # No explicit output: we're done
Chris@87 4901 if out is None:
Chris@87 4902 return result
Chris@87 4903 if isinstance(out, MaskedArray):
Chris@87 4904 out.__setmask__(self._mask)
Chris@87 4905 return out
Chris@87 4906 round.__doc__ = ndarray.round.__doc__
Chris@87 4907
Chris@87 4908 #............................................
Chris@87 4909 def argsort(self, axis=None, kind='quicksort', order=None, fill_value=None):
Chris@87 4910 """
Chris@87 4911 Return an ndarray of indices that sort the array along the
Chris@87 4912 specified axis. Masked values are filled beforehand to
Chris@87 4913 `fill_value`.
Chris@87 4914
Chris@87 4915 Parameters
Chris@87 4916 ----------
Chris@87 4917 axis : int, optional
Chris@87 4918 Axis along which to sort. The default is -1 (last axis).
Chris@87 4919 If None, the flattened array is used.
Chris@87 4920 fill_value : var, optional
Chris@87 4921 Value used to fill the array before sorting.
Chris@87 4922 The default is the `fill_value` attribute of the input array.
Chris@87 4923 kind : {'quicksort', 'mergesort', 'heapsort'}, optional
Chris@87 4924 Sorting algorithm.
Chris@87 4925 order : list, optional
Chris@87 4926 When `a` is an array with fields defined, this argument specifies
Chris@87 4927 which fields to compare first, second, etc. Not all fields need be
Chris@87 4928 specified.
Chris@87 4929
Chris@87 4930 Returns
Chris@87 4931 -------
Chris@87 4932 index_array : ndarray, int
Chris@87 4933 Array of indices that sort `a` along the specified axis.
Chris@87 4934 In other words, ``a[index_array]`` yields a sorted `a`.
Chris@87 4935
Chris@87 4936 See Also
Chris@87 4937 --------
Chris@87 4938 sort : Describes sorting algorithms used.
Chris@87 4939 lexsort : Indirect stable sort with multiple keys.
Chris@87 4940 ndarray.sort : Inplace sort.
Chris@87 4941
Chris@87 4942 Notes
Chris@87 4943 -----
Chris@87 4944 See `sort` for notes on the different sorting algorithms.
Chris@87 4945
Chris@87 4946 Examples
Chris@87 4947 --------
Chris@87 4948 >>> a = np.ma.array([3,2,1], mask=[False, False, True])
Chris@87 4949 >>> a
Chris@87 4950 masked_array(data = [3 2 --],
Chris@87 4951 mask = [False False True],
Chris@87 4952 fill_value = 999999)
Chris@87 4953 >>> a.argsort()
Chris@87 4954 array([1, 0, 2])
Chris@87 4955
Chris@87 4956 """
Chris@87 4957 if fill_value is None:
Chris@87 4958 fill_value = default_fill_value(self)
Chris@87 4959 d = self.filled(fill_value).view(ndarray)
Chris@87 4960 return d.argsort(axis=axis, kind=kind, order=order)
Chris@87 4961
Chris@87 4962
Chris@87 4963 def argmin(self, axis=None, fill_value=None, out=None):
Chris@87 4964 """
Chris@87 4965 Return array of indices to the minimum values along the given axis.
Chris@87 4966
Chris@87 4967 Parameters
Chris@87 4968 ----------
Chris@87 4969 axis : {None, integer}
Chris@87 4970 If None, the index is into the flattened array, otherwise along
Chris@87 4971 the specified axis
Chris@87 4972 fill_value : {var}, optional
Chris@87 4973 Value used to fill in the masked values. If None, the output of
Chris@87 4974 minimum_fill_value(self._data) is used instead.
Chris@87 4975 out : {None, array}, optional
Chris@87 4976 Array into which the result can be placed. Its type is preserved
Chris@87 4977 and it must be of the right shape to hold the output.
Chris@87 4978
Chris@87 4979 Returns
Chris@87 4980 -------
Chris@87 4981 {ndarray, scalar}
Chris@87 4982 If multi-dimension input, returns a new ndarray of indices to the
Chris@87 4983 minimum values along the given axis. Otherwise, returns a scalar
Chris@87 4984 of index to the minimum values along the given axis.
Chris@87 4985
Chris@87 4986 Examples
Chris@87 4987 --------
Chris@87 4988 >>> x = np.ma.array(arange(4), mask=[1,1,0,0])
Chris@87 4989 >>> x.shape = (2,2)
Chris@87 4990 >>> print x
Chris@87 4991 [[-- --]
Chris@87 4992 [2 3]]
Chris@87 4993 >>> print x.argmin(axis=0, fill_value=-1)
Chris@87 4994 [0 0]
Chris@87 4995 >>> print x.argmin(axis=0, fill_value=9)
Chris@87 4996 [1 1]
Chris@87 4997
Chris@87 4998 """
Chris@87 4999 if fill_value is None:
Chris@87 5000 fill_value = minimum_fill_value(self)
Chris@87 5001 d = self.filled(fill_value).view(ndarray)
Chris@87 5002 return d.argmin(axis, out=out)
Chris@87 5003
Chris@87 5004
Chris@87 5005 def argmax(self, axis=None, fill_value=None, out=None):
Chris@87 5006 """
Chris@87 5007 Returns array of indices of the maximum values along the given axis.
Chris@87 5008 Masked values are treated as if they had the value fill_value.
Chris@87 5009
Chris@87 5010 Parameters
Chris@87 5011 ----------
Chris@87 5012 axis : {None, integer}
Chris@87 5013 If None, the index is into the flattened array, otherwise along
Chris@87 5014 the specified axis
Chris@87 5015 fill_value : {var}, optional
Chris@87 5016 Value used to fill in the masked values. If None, the output of
Chris@87 5017 maximum_fill_value(self._data) is used instead.
Chris@87 5018 out : {None, array}, optional
Chris@87 5019 Array into which the result can be placed. Its type is preserved
Chris@87 5020 and it must be of the right shape to hold the output.
Chris@87 5021
Chris@87 5022 Returns
Chris@87 5023 -------
Chris@87 5024 index_array : {integer_array}
Chris@87 5025
Chris@87 5026 Examples
Chris@87 5027 --------
Chris@87 5028 >>> a = np.arange(6).reshape(2,3)
Chris@87 5029 >>> a.argmax()
Chris@87 5030 5
Chris@87 5031 >>> a.argmax(0)
Chris@87 5032 array([1, 1, 1])
Chris@87 5033 >>> a.argmax(1)
Chris@87 5034 array([2, 2])
Chris@87 5035
Chris@87 5036 """
Chris@87 5037 if fill_value is None:
Chris@87 5038 fill_value = maximum_fill_value(self._data)
Chris@87 5039 d = self.filled(fill_value).view(ndarray)
Chris@87 5040 return d.argmax(axis, out=out)
Chris@87 5041
Chris@87 5042
Chris@87 5043 def sort(self, axis= -1, kind='quicksort', order=None,
Chris@87 5044 endwith=True, fill_value=None):
Chris@87 5045 """
Chris@87 5046 Sort the array, in-place
Chris@87 5047
Chris@87 5048 Parameters
Chris@87 5049 ----------
Chris@87 5050 a : array_like
Chris@87 5051 Array to be sorted.
Chris@87 5052 axis : int, optional
Chris@87 5053 Axis along which to sort. If None, the array is flattened before
Chris@87 5054 sorting. The default is -1, which sorts along the last axis.
Chris@87 5055 kind : {'quicksort', 'mergesort', 'heapsort'}, optional
Chris@87 5056 Sorting algorithm. Default is 'quicksort'.
Chris@87 5057 order : list, optional
Chris@87 5058 When `a` is a structured array, this argument specifies which fields
Chris@87 5059 to compare first, second, and so on. This list does not need to
Chris@87 5060 include all of the fields.
Chris@87 5061 endwith : {True, False}, optional
Chris@87 5062 Whether missing values (if any) should be forced in the upper indices
Chris@87 5063 (at the end of the array) (True) or lower indices (at the beginning).
Chris@87 5064 When the array contains unmasked values of the largest (or smallest if
Chris@87 5065 False) representable value of the datatype the ordering of these values
Chris@87 5066 and the masked values is undefined. To enforce the masked values are
Chris@87 5067 at the end (beginning) in this case one must sort the mask.
Chris@87 5068 fill_value : {var}, optional
Chris@87 5069 Value used internally for the masked values.
Chris@87 5070 If ``fill_value`` is not None, it supersedes ``endwith``.
Chris@87 5071
Chris@87 5072 Returns
Chris@87 5073 -------
Chris@87 5074 sorted_array : ndarray
Chris@87 5075 Array of the same type and shape as `a`.
Chris@87 5076
Chris@87 5077 See Also
Chris@87 5078 --------
Chris@87 5079 ndarray.sort : Method to sort an array in-place.
Chris@87 5080 argsort : Indirect sort.
Chris@87 5081 lexsort : Indirect stable sort on multiple keys.
Chris@87 5082 searchsorted : Find elements in a sorted array.
Chris@87 5083
Chris@87 5084 Notes
Chris@87 5085 -----
Chris@87 5086 See ``sort`` for notes on the different sorting algorithms.
Chris@87 5087
Chris@87 5088 Examples
Chris@87 5089 --------
Chris@87 5090 >>> a = ma.array([1, 2, 5, 4, 3],mask=[0, 1, 0, 1, 0])
Chris@87 5091 >>> # Default
Chris@87 5092 >>> a.sort()
Chris@87 5093 >>> print a
Chris@87 5094 [1 3 5 -- --]
Chris@87 5095
Chris@87 5096 >>> a = ma.array([1, 2, 5, 4, 3],mask=[0, 1, 0, 1, 0])
Chris@87 5097 >>> # Put missing values in the front
Chris@87 5098 >>> a.sort(endwith=False)
Chris@87 5099 >>> print a
Chris@87 5100 [-- -- 1 3 5]
Chris@87 5101
Chris@87 5102 >>> a = ma.array([1, 2, 5, 4, 3],mask=[0, 1, 0, 1, 0])
Chris@87 5103 >>> # fill_value takes over endwith
Chris@87 5104 >>> a.sort(endwith=False, fill_value=3)
Chris@87 5105 >>> print a
Chris@87 5106 [1 -- -- 3 5]
Chris@87 5107
Chris@87 5108 """
Chris@87 5109 if self._mask is nomask:
Chris@87 5110 ndarray.sort(self, axis=axis, kind=kind, order=order)
Chris@87 5111 else:
Chris@87 5112 if self is masked:
Chris@87 5113 return self
Chris@87 5114 if fill_value is None:
Chris@87 5115 if endwith:
Chris@87 5116 # nan > inf
Chris@87 5117 if np.issubdtype(self.dtype, np.floating):
Chris@87 5118 filler = np.nan
Chris@87 5119 else:
Chris@87 5120 filler = minimum_fill_value(self)
Chris@87 5121 else:
Chris@87 5122 filler = maximum_fill_value(self)
Chris@87 5123 else:
Chris@87 5124 filler = fill_value
Chris@87 5125
Chris@87 5126 sidx = self.filled(filler).argsort(axis=axis, kind=kind,
Chris@87 5127 order=order)
Chris@87 5128 # save meshgrid memory for 1d arrays
Chris@87 5129 if self.ndim == 1:
Chris@87 5130 idx = sidx
Chris@87 5131 else:
Chris@87 5132 idx = np.meshgrid(*[np.arange(x) for x in self.shape], sparse=True,
Chris@87 5133 indexing='ij')
Chris@87 5134 idx[axis] = sidx
Chris@87 5135 tmp_mask = self._mask[idx].flat
Chris@87 5136 tmp_data = self._data[idx].flat
Chris@87 5137 self._data.flat = tmp_data
Chris@87 5138 self._mask.flat = tmp_mask
Chris@87 5139 return
Chris@87 5140
Chris@87 5141 #............................................
Chris@87 5142 def min(self, axis=None, out=None, fill_value=None):
Chris@87 5143 """
Chris@87 5144 Return the minimum along a given axis.
Chris@87 5145
Chris@87 5146 Parameters
Chris@87 5147 ----------
Chris@87 5148 axis : {None, int}, optional
Chris@87 5149 Axis along which to operate. By default, ``axis`` is None and the
Chris@87 5150 flattened input is used.
Chris@87 5151 out : array_like, optional
Chris@87 5152 Alternative output array in which to place the result. Must be of
Chris@87 5153 the same shape and buffer length as the expected output.
Chris@87 5154 fill_value : {var}, optional
Chris@87 5155 Value used to fill in the masked values.
Chris@87 5156 If None, use the output of `minimum_fill_value`.
Chris@87 5157
Chris@87 5158 Returns
Chris@87 5159 -------
Chris@87 5160 amin : array_like
Chris@87 5161 New array holding the result.
Chris@87 5162 If ``out`` was specified, ``out`` is returned.
Chris@87 5163
Chris@87 5164 See Also
Chris@87 5165 --------
Chris@87 5166 minimum_fill_value
Chris@87 5167 Returns the minimum filling value for a given datatype.
Chris@87 5168
Chris@87 5169 """
Chris@87 5170 _mask = ndarray.__getattribute__(self, '_mask')
Chris@87 5171 newmask = _check_mask_axis(_mask, axis)
Chris@87 5172 if fill_value is None:
Chris@87 5173 fill_value = minimum_fill_value(self)
Chris@87 5174 # No explicit output
Chris@87 5175 if out is None:
Chris@87 5176 result = self.filled(fill_value).min(axis=axis, out=out).view(type(self))
Chris@87 5177 if result.ndim:
Chris@87 5178 # Set the mask
Chris@87 5179 result.__setmask__(newmask)
Chris@87 5180 # Get rid of Infs
Chris@87 5181 if newmask.ndim:
Chris@87 5182 np.copyto(result, result.fill_value, where=newmask)
Chris@87 5183 elif newmask:
Chris@87 5184 result = masked
Chris@87 5185 return result
Chris@87 5186 # Explicit output
Chris@87 5187 result = self.filled(fill_value).min(axis=axis, out=out)
Chris@87 5188 if isinstance(out, MaskedArray):
Chris@87 5189 outmask = getattr(out, '_mask', nomask)
Chris@87 5190 if (outmask is nomask):
Chris@87 5191 outmask = out._mask = make_mask_none(out.shape)
Chris@87 5192 outmask.flat = newmask
Chris@87 5193 else:
Chris@87 5194 if out.dtype.kind in 'biu':
Chris@87 5195 errmsg = "Masked data information would be lost in one or more"\
Chris@87 5196 " location."
Chris@87 5197 raise MaskError(errmsg)
Chris@87 5198 np.copyto(out, np.nan, where=newmask)
Chris@87 5199 return out
Chris@87 5200
Chris@87 5201 def mini(self, axis=None):
Chris@87 5202 """
Chris@87 5203 Return the array minimum along the specified axis.
Chris@87 5204
Chris@87 5205 Parameters
Chris@87 5206 ----------
Chris@87 5207 axis : int, optional
Chris@87 5208 The axis along which to find the minima. Default is None, in which case
Chris@87 5209 the minimum value in the whole array is returned.
Chris@87 5210
Chris@87 5211 Returns
Chris@87 5212 -------
Chris@87 5213 min : scalar or MaskedArray
Chris@87 5214 If `axis` is None, the result is a scalar. Otherwise, if `axis` is
Chris@87 5215 given and the array is at least 2-D, the result is a masked array with
Chris@87 5216 dimension one smaller than the array on which `mini` is called.
Chris@87 5217
Chris@87 5218 Examples
Chris@87 5219 --------
Chris@87 5220 >>> x = np.ma.array(np.arange(6), mask=[0 ,1, 0, 0, 0 ,1]).reshape(3, 2)
Chris@87 5221 >>> print x
Chris@87 5222 [[0 --]
Chris@87 5223 [2 3]
Chris@87 5224 [4 --]]
Chris@87 5225 >>> x.mini()
Chris@87 5226 0
Chris@87 5227 >>> x.mini(axis=0)
Chris@87 5228 masked_array(data = [0 3],
Chris@87 5229 mask = [False False],
Chris@87 5230 fill_value = 999999)
Chris@87 5231 >>> print x.mini(axis=1)
Chris@87 5232 [0 2 4]
Chris@87 5233
Chris@87 5234 """
Chris@87 5235 if axis is None:
Chris@87 5236 return minimum(self)
Chris@87 5237 else:
Chris@87 5238 return minimum.reduce(self, axis)
Chris@87 5239
Chris@87 5240 #........................
Chris@87 5241 def max(self, axis=None, out=None, fill_value=None):
Chris@87 5242 """
Chris@87 5243 Return the maximum along a given axis.
Chris@87 5244
Chris@87 5245 Parameters
Chris@87 5246 ----------
Chris@87 5247 axis : {None, int}, optional
Chris@87 5248 Axis along which to operate. By default, ``axis`` is None and the
Chris@87 5249 flattened input is used.
Chris@87 5250 out : array_like, optional
Chris@87 5251 Alternative output array in which to place the result. Must
Chris@87 5252 be of the same shape and buffer length as the expected output.
Chris@87 5253 fill_value : {var}, optional
Chris@87 5254 Value used to fill in the masked values.
Chris@87 5255 If None, use the output of maximum_fill_value().
Chris@87 5256
Chris@87 5257 Returns
Chris@87 5258 -------
Chris@87 5259 amax : array_like
Chris@87 5260 New array holding the result.
Chris@87 5261 If ``out`` was specified, ``out`` is returned.
Chris@87 5262
Chris@87 5263 See Also
Chris@87 5264 --------
Chris@87 5265 maximum_fill_value
Chris@87 5266 Returns the maximum filling value for a given datatype.
Chris@87 5267
Chris@87 5268 """
Chris@87 5269 _mask = ndarray.__getattribute__(self, '_mask')
Chris@87 5270 newmask = _check_mask_axis(_mask, axis)
Chris@87 5271 if fill_value is None:
Chris@87 5272 fill_value = maximum_fill_value(self)
Chris@87 5273 # No explicit output
Chris@87 5274 if out is None:
Chris@87 5275 result = self.filled(fill_value).max(axis=axis, out=out).view(type(self))
Chris@87 5276 if result.ndim:
Chris@87 5277 # Set the mask
Chris@87 5278 result.__setmask__(newmask)
Chris@87 5279 # Get rid of Infs
Chris@87 5280 if newmask.ndim:
Chris@87 5281 np.copyto(result, result.fill_value, where=newmask)
Chris@87 5282 elif newmask:
Chris@87 5283 result = masked
Chris@87 5284 return result
Chris@87 5285 # Explicit output
Chris@87 5286 result = self.filled(fill_value).max(axis=axis, out=out)
Chris@87 5287 if isinstance(out, MaskedArray):
Chris@87 5288 outmask = getattr(out, '_mask', nomask)
Chris@87 5289 if (outmask is nomask):
Chris@87 5290 outmask = out._mask = make_mask_none(out.shape)
Chris@87 5291 outmask.flat = newmask
Chris@87 5292 else:
Chris@87 5293
Chris@87 5294 if out.dtype.kind in 'biu':
Chris@87 5295 errmsg = "Masked data information would be lost in one or more"\
Chris@87 5296 " location."
Chris@87 5297 raise MaskError(errmsg)
Chris@87 5298 np.copyto(out, np.nan, where=newmask)
Chris@87 5299 return out
Chris@87 5300
Chris@87 5301 def ptp(self, axis=None, out=None, fill_value=None):
Chris@87 5302 """
Chris@87 5303 Return (maximum - minimum) along the the given dimension
Chris@87 5304 (i.e. peak-to-peak value).
Chris@87 5305
Chris@87 5306 Parameters
Chris@87 5307 ----------
Chris@87 5308 axis : {None, int}, optional
Chris@87 5309 Axis along which to find the peaks. If None (default) the
Chris@87 5310 flattened array is used.
Chris@87 5311 out : {None, array_like}, optional
Chris@87 5312 Alternative output array in which to place the result. It must
Chris@87 5313 have the same shape and buffer length as the expected output
Chris@87 5314 but the type will be cast if necessary.
Chris@87 5315 fill_value : {var}, optional
Chris@87 5316 Value used to fill in the masked values.
Chris@87 5317
Chris@87 5318 Returns
Chris@87 5319 -------
Chris@87 5320 ptp : ndarray.
Chris@87 5321 A new array holding the result, unless ``out`` was
Chris@87 5322 specified, in which case a reference to ``out`` is returned.
Chris@87 5323
Chris@87 5324 """
Chris@87 5325 if out is None:
Chris@87 5326 result = self.max(axis=axis, fill_value=fill_value)
Chris@87 5327 result -= self.min(axis=axis, fill_value=fill_value)
Chris@87 5328 return result
Chris@87 5329 out.flat = self.max(axis=axis, out=out, fill_value=fill_value)
Chris@87 5330 min_value = self.min(axis=axis, fill_value=fill_value)
Chris@87 5331 np.subtract(out, min_value, out=out, casting='unsafe')
Chris@87 5332 return out
Chris@87 5333
Chris@87 5334 def take(self, indices, axis=None, out=None, mode='raise'):
Chris@87 5335 """
Chris@87 5336 """
Chris@87 5337 (_data, _mask) = (self._data, self._mask)
Chris@87 5338 cls = type(self)
Chris@87 5339 # Make sure the indices are not masked
Chris@87 5340 maskindices = getattr(indices, '_mask', nomask)
Chris@87 5341 if maskindices is not nomask:
Chris@87 5342 indices = indices.filled(0)
Chris@87 5343 # Get the data
Chris@87 5344 if out is None:
Chris@87 5345 out = _data.take(indices, axis=axis, mode=mode).view(cls)
Chris@87 5346 else:
Chris@87 5347 np.take(_data, indices, axis=axis, mode=mode, out=out)
Chris@87 5348 # Get the mask
Chris@87 5349 if isinstance(out, MaskedArray):
Chris@87 5350 if _mask is nomask:
Chris@87 5351 outmask = maskindices
Chris@87 5352 else:
Chris@87 5353 outmask = _mask.take(indices, axis=axis, mode=mode)
Chris@87 5354 outmask |= maskindices
Chris@87 5355 out.__setmask__(outmask)
Chris@87 5356 return out
Chris@87 5357
Chris@87 5358
Chris@87 5359 # Array methods ---------------------------------------
Chris@87 5360 copy = _arraymethod('copy')
Chris@87 5361 diagonal = _arraymethod('diagonal')
Chris@87 5362 transpose = _arraymethod('transpose')
Chris@87 5363 T = property(fget=lambda self:self.transpose())
Chris@87 5364 swapaxes = _arraymethod('swapaxes')
Chris@87 5365 clip = _arraymethod('clip', onmask=False)
Chris@87 5366 copy = _arraymethod('copy')
Chris@87 5367 squeeze = _arraymethod('squeeze')
Chris@87 5368 #--------------------------------------------
Chris@87 5369 def tolist(self, fill_value=None):
Chris@87 5370 """
Chris@87 5371 Return the data portion of the masked array as a hierarchical Python list.
Chris@87 5372
Chris@87 5373 Data items are converted to the nearest compatible Python type.
Chris@87 5374 Masked values are converted to `fill_value`. If `fill_value` is None,
Chris@87 5375 the corresponding entries in the output list will be ``None``.
Chris@87 5376
Chris@87 5377 Parameters
Chris@87 5378 ----------
Chris@87 5379 fill_value : scalar, optional
Chris@87 5380 The value to use for invalid entries. Default is None.
Chris@87 5381
Chris@87 5382 Returns
Chris@87 5383 -------
Chris@87 5384 result : list
Chris@87 5385 The Python list representation of the masked array.
Chris@87 5386
Chris@87 5387 Examples
Chris@87 5388 --------
Chris@87 5389 >>> x = np.ma.array([[1,2,3], [4,5,6], [7,8,9]], mask=[0] + [1,0]*4)
Chris@87 5390 >>> x.tolist()
Chris@87 5391 [[1, None, 3], [None, 5, None], [7, None, 9]]
Chris@87 5392 >>> x.tolist(-999)
Chris@87 5393 [[1, -999, 3], [-999, 5, -999], [7, -999, 9]]
Chris@87 5394
Chris@87 5395 """
Chris@87 5396 _mask = self._mask
Chris@87 5397 # No mask ? Just return .data.tolist ?
Chris@87 5398 if _mask is nomask:
Chris@87 5399 return self._data.tolist()
Chris@87 5400 # Explicit fill_value: fill the array and get the list
Chris@87 5401 if fill_value is not None:
Chris@87 5402 return self.filled(fill_value).tolist()
Chris@87 5403 # Structured array .............
Chris@87 5404 names = self.dtype.names
Chris@87 5405 if names:
Chris@87 5406 result = self._data.astype([(_, object) for _ in names])
Chris@87 5407 for n in names:
Chris@87 5408 result[n][_mask[n]] = None
Chris@87 5409 return result.tolist()
Chris@87 5410 # Standard arrays ...............
Chris@87 5411 if _mask is nomask:
Chris@87 5412 return [None]
Chris@87 5413 # Set temps to save time when dealing w/ marrays...
Chris@87 5414 inishape = self.shape
Chris@87 5415 result = np.array(self._data.ravel(), dtype=object)
Chris@87 5416 result[_mask.ravel()] = None
Chris@87 5417 result.shape = inishape
Chris@87 5418 return result.tolist()
Chris@87 5419 # if fill_value is not None:
Chris@87 5420 # return self.filled(fill_value).tolist()
Chris@87 5421 # result = self.filled().tolist()
Chris@87 5422 # # Set temps to save time when dealing w/ mrecarrays...
Chris@87 5423 # _mask = self._mask
Chris@87 5424 # if _mask is nomask:
Chris@87 5425 # return result
Chris@87 5426 # nbdims = self.ndim
Chris@87 5427 # dtypesize = len(self.dtype)
Chris@87 5428 # if nbdims == 0:
Chris@87 5429 # return tuple([None] * dtypesize)
Chris@87 5430 # elif nbdims == 1:
Chris@87 5431 # maskedidx = _mask.nonzero()[0].tolist()
Chris@87 5432 # if dtypesize:
Chris@87 5433 # nodata = tuple([None] * dtypesize)
Chris@87 5434 # else:
Chris@87 5435 # nodata = None
Chris@87 5436 # [operator.setitem(result, i, nodata) for i in maskedidx]
Chris@87 5437 # else:
Chris@87 5438 # for idx in zip(*[i.tolist() for i in _mask.nonzero()]):
Chris@87 5439 # tmp = result
Chris@87 5440 # for i in idx[:-1]:
Chris@87 5441 # tmp = tmp[i]
Chris@87 5442 # tmp[idx[-1]] = None
Chris@87 5443 # return result
Chris@87 5444 #........................
Chris@87 5445 def tostring(self, fill_value=None, order='C'):
Chris@87 5446 """
Chris@87 5447 This function is a compatibility alias for tobytes. Despite its name it
Chris@87 5448 returns bytes not strings.
Chris@87 5449 """
Chris@87 5450
Chris@87 5451 return self.tobytes(fill_value, order='C')
Chris@87 5452 #........................
Chris@87 5453 def tobytes(self, fill_value=None, order='C'):
Chris@87 5454 """
Chris@87 5455 Return the array data as a string containing the raw bytes in the array.
Chris@87 5456
Chris@87 5457 The array is filled with a fill value before the string conversion.
Chris@87 5458
Chris@87 5459 .. versionadded:: 1.9.0
Chris@87 5460
Chris@87 5461 Parameters
Chris@87 5462 ----------
Chris@87 5463 fill_value : scalar, optional
Chris@87 5464 Value used to fill in the masked values. Deafult is None, in which
Chris@87 5465 case `MaskedArray.fill_value` is used.
Chris@87 5466 order : {'C','F','A'}, optional
Chris@87 5467 Order of the data item in the copy. Default is 'C'.
Chris@87 5468
Chris@87 5469 - 'C' -- C order (row major).
Chris@87 5470 - 'F' -- Fortran order (column major).
Chris@87 5471 - 'A' -- Any, current order of array.
Chris@87 5472 - None -- Same as 'A'.
Chris@87 5473
Chris@87 5474 See Also
Chris@87 5475 --------
Chris@87 5476 ndarray.tobytes
Chris@87 5477 tolist, tofile
Chris@87 5478
Chris@87 5479 Notes
Chris@87 5480 -----
Chris@87 5481 As for `ndarray.tobytes`, information about the shape, dtype, etc.,
Chris@87 5482 but also about `fill_value`, will be lost.
Chris@87 5483
Chris@87 5484 Examples
Chris@87 5485 --------
Chris@87 5486 >>> x = np.ma.array(np.array([[1, 2], [3, 4]]), mask=[[0, 1], [1, 0]])
Chris@87 5487 >>> x.tobytes()
Chris@87 5488 '\\x01\\x00\\x00\\x00?B\\x0f\\x00?B\\x0f\\x00\\x04\\x00\\x00\\x00'
Chris@87 5489
Chris@87 5490 """
Chris@87 5491 return self.filled(fill_value).tobytes(order=order)
Chris@87 5492 #........................
Chris@87 5493 def tofile(self, fid, sep="", format="%s"):
Chris@87 5494 """
Chris@87 5495 Save a masked array to a file in binary format.
Chris@87 5496
Chris@87 5497 .. warning::
Chris@87 5498 This function is not implemented yet.
Chris@87 5499
Chris@87 5500 Raises
Chris@87 5501 ------
Chris@87 5502 NotImplementedError
Chris@87 5503 When `tofile` is called.
Chris@87 5504
Chris@87 5505 """
Chris@87 5506 raise NotImplementedError("Not implemented yet, sorry...")
Chris@87 5507
Chris@87 5508 def toflex(self):
Chris@87 5509 """
Chris@87 5510 Transforms a masked array into a flexible-type array.
Chris@87 5511
Chris@87 5512 The flexible type array that is returned will have two fields:
Chris@87 5513
Chris@87 5514 * the ``_data`` field stores the ``_data`` part of the array.
Chris@87 5515 * the ``_mask`` field stores the ``_mask`` part of the array.
Chris@87 5516
Chris@87 5517 Parameters
Chris@87 5518 ----------
Chris@87 5519 None
Chris@87 5520
Chris@87 5521 Returns
Chris@87 5522 -------
Chris@87 5523 record : ndarray
Chris@87 5524 A new flexible-type `ndarray` with two fields: the first element
Chris@87 5525 containing a value, the second element containing the corresponding
Chris@87 5526 mask boolean. The returned record shape matches self.shape.
Chris@87 5527
Chris@87 5528 Notes
Chris@87 5529 -----
Chris@87 5530 A side-effect of transforming a masked array into a flexible `ndarray` is
Chris@87 5531 that meta information (``fill_value``, ...) will be lost.
Chris@87 5532
Chris@87 5533 Examples
Chris@87 5534 --------
Chris@87 5535 >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
Chris@87 5536 >>> print x
Chris@87 5537 [[1 -- 3]
Chris@87 5538 [-- 5 --]
Chris@87 5539 [7 -- 9]]
Chris@87 5540 >>> print x.toflex()
Chris@87 5541 [[(1, False) (2, True) (3, False)]
Chris@87 5542 [(4, True) (5, False) (6, True)]
Chris@87 5543 [(7, False) (8, True) (9, False)]]
Chris@87 5544
Chris@87 5545 """
Chris@87 5546 # Get the basic dtype ....
Chris@87 5547 ddtype = self.dtype
Chris@87 5548 # Make sure we have a mask
Chris@87 5549 _mask = self._mask
Chris@87 5550 if _mask is None:
Chris@87 5551 _mask = make_mask_none(self.shape, ddtype)
Chris@87 5552 # And get its dtype
Chris@87 5553 mdtype = self._mask.dtype
Chris@87 5554 #
Chris@87 5555 record = np.ndarray(shape=self.shape,
Chris@87 5556 dtype=[('_data', ddtype), ('_mask', mdtype)])
Chris@87 5557 record['_data'] = self._data
Chris@87 5558 record['_mask'] = self._mask
Chris@87 5559 return record
Chris@87 5560 torecords = toflex
Chris@87 5561 #--------------------------------------------
Chris@87 5562 # Pickling
Chris@87 5563 def __getstate__(self):
Chris@87 5564 """Return the internal state of the masked array, for pickling
Chris@87 5565 purposes.
Chris@87 5566
Chris@87 5567 """
Chris@87 5568 cf = 'CF'[self.flags.fnc]
Chris@87 5569 state = (1,
Chris@87 5570 self.shape,
Chris@87 5571 self.dtype,
Chris@87 5572 self.flags.fnc,
Chris@87 5573 self._data.tobytes(cf),
Chris@87 5574 #self._data.tolist(),
Chris@87 5575 getmaskarray(self).tobytes(cf),
Chris@87 5576 #getmaskarray(self).tolist(),
Chris@87 5577 self._fill_value,
Chris@87 5578 )
Chris@87 5579 return state
Chris@87 5580 #
Chris@87 5581 def __setstate__(self, state):
Chris@87 5582 """Restore the internal state of the masked array, for
Chris@87 5583 pickling purposes. ``state`` is typically the output of the
Chris@87 5584 ``__getstate__`` output, and is a 5-tuple:
Chris@87 5585
Chris@87 5586 - class name
Chris@87 5587 - a tuple giving the shape of the data
Chris@87 5588 - a typecode for the data
Chris@87 5589 - a binary string for the data
Chris@87 5590 - a binary string for the mask.
Chris@87 5591
Chris@87 5592 """
Chris@87 5593 (_, shp, typ, isf, raw, msk, flv) = state
Chris@87 5594 ndarray.__setstate__(self, (shp, typ, isf, raw))
Chris@87 5595 self._mask.__setstate__((shp, make_mask_descr(typ), isf, msk))
Chris@87 5596 self.fill_value = flv
Chris@87 5597 #
Chris@87 5598 def __reduce__(self):
Chris@87 5599 """Return a 3-tuple for pickling a MaskedArray.
Chris@87 5600
Chris@87 5601 """
Chris@87 5602 return (_mareconstruct,
Chris@87 5603 (self.__class__, self._baseclass, (0,), 'b',),
Chris@87 5604 self.__getstate__())
Chris@87 5605 #
Chris@87 5606 def __deepcopy__(self, memo=None):
Chris@87 5607 from copy import deepcopy
Chris@87 5608 copied = MaskedArray.__new__(type(self), self, copy=True)
Chris@87 5609 if memo is None:
Chris@87 5610 memo = {}
Chris@87 5611 memo[id(self)] = copied
Chris@87 5612 for (k, v) in self.__dict__.items():
Chris@87 5613 copied.__dict__[k] = deepcopy(v, memo)
Chris@87 5614 return copied
Chris@87 5615
Chris@87 5616
Chris@87 5617 def _mareconstruct(subtype, baseclass, baseshape, basetype,):
Chris@87 5618 """Internal function that builds a new MaskedArray from the
Chris@87 5619 information stored in a pickle.
Chris@87 5620
Chris@87 5621 """
Chris@87 5622 _data = ndarray.__new__(baseclass, baseshape, basetype)
Chris@87 5623 _mask = ndarray.__new__(ndarray, baseshape, make_mask_descr(basetype))
Chris@87 5624 return subtype.__new__(subtype, _data, mask=_mask, dtype=basetype,)
Chris@87 5625
Chris@87 5626
Chris@87 5627
Chris@87 5628
Chris@87 5629
Chris@87 5630
Chris@87 5631 class mvoid(MaskedArray):
Chris@87 5632 """
Chris@87 5633 Fake a 'void' object to use for masked array with structured dtypes.
Chris@87 5634 """
Chris@87 5635 #
Chris@87 5636 def __new__(self, data, mask=nomask, dtype=None, fill_value=None,
Chris@87 5637 hardmask=False, copy=False, subok=True):
Chris@87 5638 _data = np.array(data, copy=copy, subok=subok, dtype=dtype)
Chris@87 5639 _data = _data.view(self)
Chris@87 5640 _data._hardmask = hardmask
Chris@87 5641 if mask is not nomask:
Chris@87 5642 if isinstance(mask, np.void):
Chris@87 5643 _data._mask = mask
Chris@87 5644 else:
Chris@87 5645 try:
Chris@87 5646 # Mask is already a 0D array
Chris@87 5647 _data._mask = np.void(mask)
Chris@87 5648 except TypeError:
Chris@87 5649 # Transform the mask to a void
Chris@87 5650 mdtype = make_mask_descr(dtype)
Chris@87 5651 _data._mask = np.array(mask, dtype=mdtype)[()]
Chris@87 5652 if fill_value is not None:
Chris@87 5653 _data.fill_value = fill_value
Chris@87 5654 return _data
Chris@87 5655
Chris@87 5656 def _get_data(self):
Chris@87 5657 # Make sure that the _data part is a np.void
Chris@87 5658 return self.view(ndarray)[()]
Chris@87 5659 _data = property(fget=_get_data)
Chris@87 5660
Chris@87 5661 def __getitem__(self, indx):
Chris@87 5662 "Get the index..."
Chris@87 5663 m = self._mask
Chris@87 5664 if m is not nomask and m[indx]:
Chris@87 5665 return masked
Chris@87 5666 return self._data[indx]
Chris@87 5667
Chris@87 5668 def __setitem__(self, indx, value):
Chris@87 5669 self._data[indx] = value
Chris@87 5670 if self._hardmask:
Chris@87 5671 self._mask[indx] |= getattr(value, "_mask", False)
Chris@87 5672 else:
Chris@87 5673 self._mask[indx] = getattr(value, "_mask", False)
Chris@87 5674
Chris@87 5675 def __str__(self):
Chris@87 5676 m = self._mask
Chris@87 5677 if (m is nomask):
Chris@87 5678 return self._data.__str__()
Chris@87 5679 m = tuple(m)
Chris@87 5680 if (not any(m)):
Chris@87 5681 return self._data.__str__()
Chris@87 5682 r = self._data.tolist()
Chris@87 5683 p = masked_print_option
Chris@87 5684 if not p.enabled():
Chris@87 5685 p = 'N/A'
Chris@87 5686 else:
Chris@87 5687 p = str(p)
Chris@87 5688 r = [(str(_), p)[int(_m)] for (_, _m) in zip(r, m)]
Chris@87 5689 return "(%s)" % ", ".join(r)
Chris@87 5690
Chris@87 5691 def __repr__(self):
Chris@87 5692 m = self._mask
Chris@87 5693 if (m is nomask):
Chris@87 5694 return self._data.__repr__()
Chris@87 5695 m = tuple(m)
Chris@87 5696 if not any(m):
Chris@87 5697 return self._data.__repr__()
Chris@87 5698 p = masked_print_option
Chris@87 5699 if not p.enabled():
Chris@87 5700 return self.filled(self.fill_value).__repr__()
Chris@87 5701 p = str(p)
Chris@87 5702 r = [(str(_), p)[int(_m)] for (_, _m) in zip(self._data.tolist(), m)]
Chris@87 5703 return "(%s)" % ", ".join(r)
Chris@87 5704
Chris@87 5705 def __iter__(self):
Chris@87 5706 "Defines an iterator for mvoid"
Chris@87 5707 (_data, _mask) = (self._data, self._mask)
Chris@87 5708 if _mask is nomask:
Chris@87 5709 for d in _data:
Chris@87 5710 yield d
Chris@87 5711 else:
Chris@87 5712 for (d, m) in zip(_data, _mask):
Chris@87 5713 if m:
Chris@87 5714 yield masked
Chris@87 5715 else:
Chris@87 5716 yield d
Chris@87 5717
Chris@87 5718 def __len__(self):
Chris@87 5719 return self._data.__len__()
Chris@87 5720
Chris@87 5721 def filled(self, fill_value=None):
Chris@87 5722 """
Chris@87 5723 Return a copy with masked fields filled with a given value.
Chris@87 5724
Chris@87 5725 Parameters
Chris@87 5726 ----------
Chris@87 5727 fill_value : scalar, optional
Chris@87 5728 The value to use for invalid entries (None by default).
Chris@87 5729 If None, the `fill_value` attribute is used instead.
Chris@87 5730
Chris@87 5731 Returns
Chris@87 5732 -------
Chris@87 5733 filled_void
Chris@87 5734 A `np.void` object
Chris@87 5735
Chris@87 5736 See Also
Chris@87 5737 --------
Chris@87 5738 MaskedArray.filled
Chris@87 5739
Chris@87 5740 """
Chris@87 5741 return asarray(self).filled(fill_value)[()]
Chris@87 5742
Chris@87 5743 def tolist(self):
Chris@87 5744 """
Chris@87 5745 Transforms the mvoid object into a tuple.
Chris@87 5746
Chris@87 5747 Masked fields are replaced by None.
Chris@87 5748
Chris@87 5749 Returns
Chris@87 5750 -------
Chris@87 5751 returned_tuple
Chris@87 5752 Tuple of fields
Chris@87 5753 """
Chris@87 5754 _mask = self._mask
Chris@87 5755 if _mask is nomask:
Chris@87 5756 return self._data.tolist()
Chris@87 5757 result = []
Chris@87 5758 for (d, m) in zip(self._data, self._mask):
Chris@87 5759 if m:
Chris@87 5760 result.append(None)
Chris@87 5761 else:
Chris@87 5762 # .item() makes sure we return a standard Python object
Chris@87 5763 result.append(d.item())
Chris@87 5764 return tuple(result)
Chris@87 5765
Chris@87 5766
Chris@87 5767
Chris@87 5768 #####--------------------------------------------------------------------------
Chris@87 5769 #---- --- Shortcuts ---
Chris@87 5770 #####---------------------------------------------------------------------------
Chris@87 5771 def isMaskedArray(x):
Chris@87 5772 """
Chris@87 5773 Test whether input is an instance of MaskedArray.
Chris@87 5774
Chris@87 5775 This function returns True if `x` is an instance of MaskedArray
Chris@87 5776 and returns False otherwise. Any object is accepted as input.
Chris@87 5777
Chris@87 5778 Parameters
Chris@87 5779 ----------
Chris@87 5780 x : object
Chris@87 5781 Object to test.
Chris@87 5782
Chris@87 5783 Returns
Chris@87 5784 -------
Chris@87 5785 result : bool
Chris@87 5786 True if `x` is a MaskedArray.
Chris@87 5787
Chris@87 5788 See Also
Chris@87 5789 --------
Chris@87 5790 isMA : Alias to isMaskedArray.
Chris@87 5791 isarray : Alias to isMaskedArray.
Chris@87 5792
Chris@87 5793 Examples
Chris@87 5794 --------
Chris@87 5795 >>> import numpy.ma as ma
Chris@87 5796 >>> a = np.eye(3, 3)
Chris@87 5797 >>> a
Chris@87 5798 array([[ 1., 0., 0.],
Chris@87 5799 [ 0., 1., 0.],
Chris@87 5800 [ 0., 0., 1.]])
Chris@87 5801 >>> m = ma.masked_values(a, 0)
Chris@87 5802 >>> m
Chris@87 5803 masked_array(data =
Chris@87 5804 [[1.0 -- --]
Chris@87 5805 [-- 1.0 --]
Chris@87 5806 [-- -- 1.0]],
Chris@87 5807 mask =
Chris@87 5808 [[False True True]
Chris@87 5809 [ True False True]
Chris@87 5810 [ True True False]],
Chris@87 5811 fill_value=0.0)
Chris@87 5812 >>> ma.isMaskedArray(a)
Chris@87 5813 False
Chris@87 5814 >>> ma.isMaskedArray(m)
Chris@87 5815 True
Chris@87 5816 >>> ma.isMaskedArray([0, 1, 2])
Chris@87 5817 False
Chris@87 5818
Chris@87 5819 """
Chris@87 5820 return isinstance(x, MaskedArray)
Chris@87 5821 isarray = isMaskedArray
Chris@87 5822 isMA = isMaskedArray #backward compatibility
Chris@87 5823
Chris@87 5824 # We define the masked singleton as a float for higher precedence...
Chris@87 5825 # Note that it can be tricky sometimes w/ type comparison
Chris@87 5826
Chris@87 5827 class MaskedConstant(MaskedArray):
Chris@87 5828 #
Chris@87 5829 _data = data = np.array(0.)
Chris@87 5830 _mask = mask = np.array(True)
Chris@87 5831 _baseclass = ndarray
Chris@87 5832 #
Chris@87 5833 def __new__(self):
Chris@87 5834 return self._data.view(self)
Chris@87 5835 #
Chris@87 5836 def __array_finalize__(self, obj):
Chris@87 5837 return
Chris@87 5838 #
Chris@87 5839 def __array_wrap__(self, obj):
Chris@87 5840 return self
Chris@87 5841 #
Chris@87 5842 def __str__(self):
Chris@87 5843 return str(masked_print_option._display)
Chris@87 5844 #
Chris@87 5845 def __repr__(self):
Chris@87 5846 return 'masked'
Chris@87 5847 #
Chris@87 5848 def flatten(self):
Chris@87 5849 return masked_array([self._data], dtype=float, mask=[True])
Chris@87 5850
Chris@87 5851 def __reduce__(self):
Chris@87 5852 """Override of MaskedArray's __reduce__.
Chris@87 5853 """
Chris@87 5854 return (self.__class__, ())
Chris@87 5855
Chris@87 5856
Chris@87 5857 masked = masked_singleton = MaskedConstant()
Chris@87 5858
Chris@87 5859
Chris@87 5860
Chris@87 5861 masked_array = MaskedArray
Chris@87 5862
Chris@87 5863 def array(data, dtype=None, copy=False, order=False,
Chris@87 5864 mask=nomask, fill_value=None,
Chris@87 5865 keep_mask=True, hard_mask=False, shrink=True, subok=True, ndmin=0,
Chris@87 5866 ):
Chris@87 5867 """array(data, dtype=None, copy=False, order=False, mask=nomask,
Chris@87 5868 fill_value=None, keep_mask=True, hard_mask=False, shrink=True,
Chris@87 5869 subok=True, ndmin=0)
Chris@87 5870
Chris@87 5871 Acts as shortcut to MaskedArray, with options in a different order
Chris@87 5872 for convenience. And backwards compatibility...
Chris@87 5873
Chris@87 5874 """
Chris@87 5875 #!!!: we should try to put 'order' somwehere
Chris@87 5876 return MaskedArray(data, mask=mask, dtype=dtype, copy=copy, subok=subok,
Chris@87 5877 keep_mask=keep_mask, hard_mask=hard_mask,
Chris@87 5878 fill_value=fill_value, ndmin=ndmin, shrink=shrink)
Chris@87 5879 array.__doc__ = masked_array.__doc__
Chris@87 5880
Chris@87 5881 def is_masked(x):
Chris@87 5882 """
Chris@87 5883 Determine whether input has masked values.
Chris@87 5884
Chris@87 5885 Accepts any object as input, but always returns False unless the
Chris@87 5886 input is a MaskedArray containing masked values.
Chris@87 5887
Chris@87 5888 Parameters
Chris@87 5889 ----------
Chris@87 5890 x : array_like
Chris@87 5891 Array to check for masked values.
Chris@87 5892
Chris@87 5893 Returns
Chris@87 5894 -------
Chris@87 5895 result : bool
Chris@87 5896 True if `x` is a MaskedArray with masked values, False otherwise.
Chris@87 5897
Chris@87 5898 Examples
Chris@87 5899 --------
Chris@87 5900 >>> import numpy.ma as ma
Chris@87 5901 >>> x = ma.masked_equal([0, 1, 0, 2, 3], 0)
Chris@87 5902 >>> x
Chris@87 5903 masked_array(data = [-- 1 -- 2 3],
Chris@87 5904 mask = [ True False True False False],
Chris@87 5905 fill_value=999999)
Chris@87 5906 >>> ma.is_masked(x)
Chris@87 5907 True
Chris@87 5908 >>> x = ma.masked_equal([0, 1, 0, 2, 3], 42)
Chris@87 5909 >>> x
Chris@87 5910 masked_array(data = [0 1 0 2 3],
Chris@87 5911 mask = False,
Chris@87 5912 fill_value=999999)
Chris@87 5913 >>> ma.is_masked(x)
Chris@87 5914 False
Chris@87 5915
Chris@87 5916 Always returns False if `x` isn't a MaskedArray.
Chris@87 5917
Chris@87 5918 >>> x = [False, True, False]
Chris@87 5919 >>> ma.is_masked(x)
Chris@87 5920 False
Chris@87 5921 >>> x = 'a string'
Chris@87 5922 >>> ma.is_masked(x)
Chris@87 5923 False
Chris@87 5924
Chris@87 5925 """
Chris@87 5926 m = getmask(x)
Chris@87 5927 if m is nomask:
Chris@87 5928 return False
Chris@87 5929 elif m.any():
Chris@87 5930 return True
Chris@87 5931 return False
Chris@87 5932
Chris@87 5933
Chris@87 5934 #####---------------------------------------------------------------------------
Chris@87 5935 #---- --- Extrema functions ---
Chris@87 5936 #####---------------------------------------------------------------------------
Chris@87 5937 class _extrema_operation(object):
Chris@87 5938 """
Chris@87 5939 Generic class for maximum/minimum functions.
Chris@87 5940
Chris@87 5941 .. note::
Chris@87 5942 This is the base class for `_maximum_operation` and
Chris@87 5943 `_minimum_operation`.
Chris@87 5944
Chris@87 5945 """
Chris@87 5946 def __call__(self, a, b=None):
Chris@87 5947 "Executes the call behavior."
Chris@87 5948 if b is None:
Chris@87 5949 return self.reduce(a)
Chris@87 5950 return where(self.compare(a, b), a, b)
Chris@87 5951 #.........
Chris@87 5952 def reduce(self, target, axis=None):
Chris@87 5953 "Reduce target along the given axis."
Chris@87 5954 target = narray(target, copy=False, subok=True)
Chris@87 5955 m = getmask(target)
Chris@87 5956 if axis is not None:
Chris@87 5957 kargs = { 'axis' : axis }
Chris@87 5958 else:
Chris@87 5959 kargs = {}
Chris@87 5960 target = target.ravel()
Chris@87 5961 if not (m is nomask):
Chris@87 5962 m = m.ravel()
Chris@87 5963 if m is nomask:
Chris@87 5964 t = self.ufunc.reduce(target, **kargs)
Chris@87 5965 else:
Chris@87 5966 target = target.filled(self.fill_value_func(target)).view(type(target))
Chris@87 5967 t = self.ufunc.reduce(target, **kargs)
Chris@87 5968 m = umath.logical_and.reduce(m, **kargs)
Chris@87 5969 if hasattr(t, '_mask'):
Chris@87 5970 t._mask = m
Chris@87 5971 elif m:
Chris@87 5972 t = masked
Chris@87 5973 return t
Chris@87 5974 #.........
Chris@87 5975 def outer (self, a, b):
Chris@87 5976 "Return the function applied to the outer product of a and b."
Chris@87 5977 ma = getmask(a)
Chris@87 5978 mb = getmask(b)
Chris@87 5979 if ma is nomask and mb is nomask:
Chris@87 5980 m = nomask
Chris@87 5981 else:
Chris@87 5982 ma = getmaskarray(a)
Chris@87 5983 mb = getmaskarray(b)
Chris@87 5984 m = logical_or.outer(ma, mb)
Chris@87 5985 result = self.ufunc.outer(filled(a), filled(b))
Chris@87 5986 if not isinstance(result, MaskedArray):
Chris@87 5987 result = result.view(MaskedArray)
Chris@87 5988 result._mask = m
Chris@87 5989 return result
Chris@87 5990
Chris@87 5991 #............................
Chris@87 5992 class _minimum_operation(_extrema_operation):
Chris@87 5993 "Object to calculate minima"
Chris@87 5994 def __init__ (self):
Chris@87 5995 """minimum(a, b) or minimum(a)
Chris@87 5996 In one argument case, returns the scalar minimum.
Chris@87 5997 """
Chris@87 5998 self.ufunc = umath.minimum
Chris@87 5999 self.afunc = amin
Chris@87 6000 self.compare = less
Chris@87 6001 self.fill_value_func = minimum_fill_value
Chris@87 6002
Chris@87 6003 #............................
Chris@87 6004 class _maximum_operation(_extrema_operation):
Chris@87 6005 "Object to calculate maxima"
Chris@87 6006 def __init__ (self):
Chris@87 6007 """maximum(a, b) or maximum(a)
Chris@87 6008 In one argument case returns the scalar maximum.
Chris@87 6009 """
Chris@87 6010 self.ufunc = umath.maximum
Chris@87 6011 self.afunc = amax
Chris@87 6012 self.compare = greater
Chris@87 6013 self.fill_value_func = maximum_fill_value
Chris@87 6014
Chris@87 6015 #..........................................................
Chris@87 6016 def min(obj, axis=None, out=None, fill_value=None):
Chris@87 6017 try:
Chris@87 6018 return obj.min(axis=axis, fill_value=fill_value, out=out)
Chris@87 6019 except (AttributeError, TypeError):
Chris@87 6020 # If obj doesn't have a min method,
Chris@87 6021 # ...or if the method doesn't accept a fill_value argument
Chris@87 6022 return asanyarray(obj).min(axis=axis, fill_value=fill_value, out=out)
Chris@87 6023 min.__doc__ = MaskedArray.min.__doc__
Chris@87 6024
Chris@87 6025 def max(obj, axis=None, out=None, fill_value=None):
Chris@87 6026 try:
Chris@87 6027 return obj.max(axis=axis, fill_value=fill_value, out=out)
Chris@87 6028 except (AttributeError, TypeError):
Chris@87 6029 # If obj doesn't have a max method,
Chris@87 6030 # ...or if the method doesn't accept a fill_value argument
Chris@87 6031 return asanyarray(obj).max(axis=axis, fill_value=fill_value, out=out)
Chris@87 6032 max.__doc__ = MaskedArray.max.__doc__
Chris@87 6033
Chris@87 6034 def ptp(obj, axis=None, out=None, fill_value=None):
Chris@87 6035 """a.ptp(axis=None) = a.max(axis)-a.min(axis)"""
Chris@87 6036 try:
Chris@87 6037 return obj.ptp(axis, out=out, fill_value=fill_value)
Chris@87 6038 except (AttributeError, TypeError):
Chris@87 6039 # If obj doesn't have a ptp method,
Chris@87 6040 # ...or if the method doesn't accept a fill_value argument
Chris@87 6041 return asanyarray(obj).ptp(axis=axis, fill_value=fill_value, out=out)
Chris@87 6042 ptp.__doc__ = MaskedArray.ptp.__doc__
Chris@87 6043
Chris@87 6044
Chris@87 6045 #####---------------------------------------------------------------------------
Chris@87 6046 #---- --- Definition of functions from the corresponding methods ---
Chris@87 6047 #####---------------------------------------------------------------------------
Chris@87 6048 class _frommethod:
Chris@87 6049 """
Chris@87 6050 Define functions from existing MaskedArray methods.
Chris@87 6051
Chris@87 6052 Parameters
Chris@87 6053 ----------
Chris@87 6054 methodname : str
Chris@87 6055 Name of the method to transform.
Chris@87 6056
Chris@87 6057 """
Chris@87 6058 def __init__(self, methodname, reversed=False):
Chris@87 6059 self.__name__ = methodname
Chris@87 6060 self.__doc__ = self.getdoc()
Chris@87 6061 self.reversed = reversed
Chris@87 6062 #
Chris@87 6063 def getdoc(self):
Chris@87 6064 "Return the doc of the function (from the doc of the method)."
Chris@87 6065 meth = getattr(MaskedArray, self.__name__, None) or\
Chris@87 6066 getattr(np, self.__name__, None)
Chris@87 6067 signature = self.__name__ + get_object_signature(meth)
Chris@87 6068 if meth is not None:
Chris@87 6069 doc = """ %s\n%s""" % (signature, getattr(meth, '__doc__', None))
Chris@87 6070 return doc
Chris@87 6071 #
Chris@87 6072 def __call__(self, a, *args, **params):
Chris@87 6073 if self.reversed:
Chris@87 6074 args = list(args)
Chris@87 6075 arr = args[0]
Chris@87 6076 args[0] = a
Chris@87 6077 a = arr
Chris@87 6078 # Get the method from the array (if possible)
Chris@87 6079 method_name = self.__name__
Chris@87 6080 method = getattr(a, method_name, None)
Chris@87 6081 if method is not None:
Chris@87 6082 return method(*args, **params)
Chris@87 6083 # Still here ? Then a is not a MaskedArray
Chris@87 6084 method = getattr(MaskedArray, method_name, None)
Chris@87 6085 if method is not None:
Chris@87 6086 return method(MaskedArray(a), *args, **params)
Chris@87 6087 # Still here ? OK, let's call the corresponding np function
Chris@87 6088 method = getattr(np, method_name)
Chris@87 6089 return method(a, *args, **params)
Chris@87 6090
Chris@87 6091 all = _frommethod('all')
Chris@87 6092 anomalies = anom = _frommethod('anom')
Chris@87 6093 any = _frommethod('any')
Chris@87 6094 compress = _frommethod('compress', reversed=True)
Chris@87 6095 cumprod = _frommethod('cumprod')
Chris@87 6096 cumsum = _frommethod('cumsum')
Chris@87 6097 copy = _frommethod('copy')
Chris@87 6098 diagonal = _frommethod('diagonal')
Chris@87 6099 harden_mask = _frommethod('harden_mask')
Chris@87 6100 ids = _frommethod('ids')
Chris@87 6101 maximum = _maximum_operation()
Chris@87 6102 mean = _frommethod('mean')
Chris@87 6103 minimum = _minimum_operation()
Chris@87 6104 nonzero = _frommethod('nonzero')
Chris@87 6105 prod = _frommethod('prod')
Chris@87 6106 product = _frommethod('prod')
Chris@87 6107 ravel = _frommethod('ravel')
Chris@87 6108 repeat = _frommethod('repeat')
Chris@87 6109 shrink_mask = _frommethod('shrink_mask')
Chris@87 6110 soften_mask = _frommethod('soften_mask')
Chris@87 6111 std = _frommethod('std')
Chris@87 6112 sum = _frommethod('sum')
Chris@87 6113 swapaxes = _frommethod('swapaxes')
Chris@87 6114 #take = _frommethod('take')
Chris@87 6115 trace = _frommethod('trace')
Chris@87 6116 var = _frommethod('var')
Chris@87 6117
Chris@87 6118 def take(a, indices, axis=None, out=None, mode='raise'):
Chris@87 6119 """
Chris@87 6120 """
Chris@87 6121 a = masked_array(a)
Chris@87 6122 return a.take(indices, axis=axis, out=out, mode=mode)
Chris@87 6123
Chris@87 6124
Chris@87 6125 #..............................................................................
Chris@87 6126 def power(a, b, third=None):
Chris@87 6127 """
Chris@87 6128 Returns element-wise base array raised to power from second array.
Chris@87 6129
Chris@87 6130 This is the masked array version of `numpy.power`. For details see
Chris@87 6131 `numpy.power`.
Chris@87 6132
Chris@87 6133 See Also
Chris@87 6134 --------
Chris@87 6135 numpy.power
Chris@87 6136
Chris@87 6137 Notes
Chris@87 6138 -----
Chris@87 6139 The *out* argument to `numpy.power` is not supported, `third` has to be
Chris@87 6140 None.
Chris@87 6141
Chris@87 6142 """
Chris@87 6143 if third is not None:
Chris@87 6144 raise MaskError("3-argument power not supported.")
Chris@87 6145 # Get the masks
Chris@87 6146 ma = getmask(a)
Chris@87 6147 mb = getmask(b)
Chris@87 6148 m = mask_or(ma, mb)
Chris@87 6149 # Get the rawdata
Chris@87 6150 fa = getdata(a)
Chris@87 6151 fb = getdata(b)
Chris@87 6152 # Get the type of the result (so that we preserve subclasses)
Chris@87 6153 if isinstance(a, MaskedArray):
Chris@87 6154 basetype = type(a)
Chris@87 6155 else:
Chris@87 6156 basetype = MaskedArray
Chris@87 6157 # Get the result and view it as a (subclass of) MaskedArray
Chris@87 6158 with np.errstate(divide='ignore', invalid='ignore'):
Chris@87 6159 result = np.where(m, fa, umath.power(fa, fb)).view(basetype)
Chris@87 6160 result._update_from(a)
Chris@87 6161 # Find where we're in trouble w/ NaNs and Infs
Chris@87 6162 invalid = np.logical_not(np.isfinite(result.view(ndarray)))
Chris@87 6163 # Add the initial mask
Chris@87 6164 if m is not nomask:
Chris@87 6165 if not (result.ndim):
Chris@87 6166 return masked
Chris@87 6167 result._mask = np.logical_or(m, invalid)
Chris@87 6168 # Fix the invalid parts
Chris@87 6169 if invalid.any():
Chris@87 6170 if not result.ndim:
Chris@87 6171 return masked
Chris@87 6172 elif result._mask is nomask:
Chris@87 6173 result._mask = invalid
Chris@87 6174 result._data[invalid] = result.fill_value
Chris@87 6175 return result
Chris@87 6176
Chris@87 6177 # if fb.dtype.char in typecodes["Integer"]:
Chris@87 6178 # return masked_array(umath.power(fa, fb), m)
Chris@87 6179 # m = mask_or(m, (fa < 0) & (fb != fb.astype(int)))
Chris@87 6180 # if m is nomask:
Chris@87 6181 # return masked_array(umath.power(fa, fb))
Chris@87 6182 # else:
Chris@87 6183 # fa = fa.copy()
Chris@87 6184 # if m.all():
Chris@87 6185 # fa.flat = 1
Chris@87 6186 # else:
Chris@87 6187 # np.copyto(fa, 1, where=m)
Chris@87 6188 # return masked_array(umath.power(fa, fb), m)
Chris@87 6189
Chris@87 6190 #..............................................................................
Chris@87 6191 def argsort(a, axis=None, kind='quicksort', order=None, fill_value=None):
Chris@87 6192 "Function version of the eponymous method."
Chris@87 6193 if fill_value is None:
Chris@87 6194 fill_value = default_fill_value(a)
Chris@87 6195 d = filled(a, fill_value)
Chris@87 6196 if axis is None:
Chris@87 6197 return d.argsort(kind=kind, order=order)
Chris@87 6198 return d.argsort(axis, kind=kind, order=order)
Chris@87 6199 argsort.__doc__ = MaskedArray.argsort.__doc__
Chris@87 6200
Chris@87 6201 def argmin(a, axis=None, fill_value=None):
Chris@87 6202 "Function version of the eponymous method."
Chris@87 6203 if fill_value is None:
Chris@87 6204 fill_value = default_fill_value(a)
Chris@87 6205 d = filled(a, fill_value)
Chris@87 6206 return d.argmin(axis=axis)
Chris@87 6207 argmin.__doc__ = MaskedArray.argmin.__doc__
Chris@87 6208
Chris@87 6209 def argmax(a, axis=None, fill_value=None):
Chris@87 6210 "Function version of the eponymous method."
Chris@87 6211 if fill_value is None:
Chris@87 6212 fill_value = default_fill_value(a)
Chris@87 6213 try:
Chris@87 6214 fill_value = -fill_value
Chris@87 6215 except:
Chris@87 6216 pass
Chris@87 6217 d = filled(a, fill_value)
Chris@87 6218 return d.argmax(axis=axis)
Chris@87 6219 argmax.__doc__ = MaskedArray.argmax.__doc__
Chris@87 6220
Chris@87 6221 def sort(a, axis= -1, kind='quicksort', order=None, endwith=True, fill_value=None):
Chris@87 6222 "Function version of the eponymous method."
Chris@87 6223 a = narray(a, copy=True, subok=True)
Chris@87 6224 if axis is None:
Chris@87 6225 a = a.flatten()
Chris@87 6226 axis = 0
Chris@87 6227 if fill_value is None:
Chris@87 6228 if endwith:
Chris@87 6229 # nan > inf
Chris@87 6230 if np.issubdtype(a.dtype, np.floating):
Chris@87 6231 filler = np.nan
Chris@87 6232 else:
Chris@87 6233 filler = minimum_fill_value(a)
Chris@87 6234 else:
Chris@87 6235 filler = maximum_fill_value(a)
Chris@87 6236 else:
Chris@87 6237 filler = fill_value
Chris@87 6238
Chris@87 6239 sindx = filled(a, filler).argsort(axis=axis, kind=kind, order=order)
Chris@87 6240
Chris@87 6241 # save meshgrid memory for 1d arrays
Chris@87 6242 if a.ndim == 1:
Chris@87 6243 indx = sindx
Chris@87 6244 else:
Chris@87 6245 indx = np.meshgrid(*[np.arange(x) for x in a.shape], sparse=True,
Chris@87 6246 indexing='ij')
Chris@87 6247 indx[axis] = sindx
Chris@87 6248 return a[indx]
Chris@87 6249 sort.__doc__ = MaskedArray.sort.__doc__
Chris@87 6250
Chris@87 6251
Chris@87 6252 def compressed(x):
Chris@87 6253 """
Chris@87 6254 Return all the non-masked data as a 1-D array.
Chris@87 6255
Chris@87 6256 This function is equivalent to calling the "compressed" method of a
Chris@87 6257 `MaskedArray`, see `MaskedArray.compressed` for details.
Chris@87 6258
Chris@87 6259 See Also
Chris@87 6260 --------
Chris@87 6261 MaskedArray.compressed
Chris@87 6262 Equivalent method.
Chris@87 6263
Chris@87 6264 """
Chris@87 6265 if not isinstance(x, MaskedArray):
Chris@87 6266 x = asanyarray(x)
Chris@87 6267 return x.compressed()
Chris@87 6268
Chris@87 6269
Chris@87 6270 def concatenate(arrays, axis=0):
Chris@87 6271 """
Chris@87 6272 Concatenate a sequence of arrays along the given axis.
Chris@87 6273
Chris@87 6274 Parameters
Chris@87 6275 ----------
Chris@87 6276 arrays : sequence of array_like
Chris@87 6277 The arrays must have the same shape, except in the dimension
Chris@87 6278 corresponding to `axis` (the first, by default).
Chris@87 6279 axis : int, optional
Chris@87 6280 The axis along which the arrays will be joined. Default is 0.
Chris@87 6281
Chris@87 6282 Returns
Chris@87 6283 -------
Chris@87 6284 result : MaskedArray
Chris@87 6285 The concatenated array with any masked entries preserved.
Chris@87 6286
Chris@87 6287 See Also
Chris@87 6288 --------
Chris@87 6289 numpy.concatenate : Equivalent function in the top-level NumPy module.
Chris@87 6290
Chris@87 6291 Examples
Chris@87 6292 --------
Chris@87 6293 >>> import numpy.ma as ma
Chris@87 6294 >>> a = ma.arange(3)
Chris@87 6295 >>> a[1] = ma.masked
Chris@87 6296 >>> b = ma.arange(2, 5)
Chris@87 6297 >>> a
Chris@87 6298 masked_array(data = [0 -- 2],
Chris@87 6299 mask = [False True False],
Chris@87 6300 fill_value = 999999)
Chris@87 6301 >>> b
Chris@87 6302 masked_array(data = [2 3 4],
Chris@87 6303 mask = False,
Chris@87 6304 fill_value = 999999)
Chris@87 6305 >>> ma.concatenate([a, b])
Chris@87 6306 masked_array(data = [0 -- 2 2 3 4],
Chris@87 6307 mask = [False True False False False False],
Chris@87 6308 fill_value = 999999)
Chris@87 6309
Chris@87 6310 """
Chris@87 6311 d = np.concatenate([getdata(a) for a in arrays], axis)
Chris@87 6312 rcls = get_masked_subclass(*arrays)
Chris@87 6313 data = d.view(rcls)
Chris@87 6314 # Check whether one of the arrays has a non-empty mask...
Chris@87 6315 for x in arrays:
Chris@87 6316 if getmask(x) is not nomask:
Chris@87 6317 break
Chris@87 6318 else:
Chris@87 6319 return data
Chris@87 6320 # OK, so we have to concatenate the masks
Chris@87 6321 dm = np.concatenate([getmaskarray(a) for a in arrays], axis)
Chris@87 6322 # If we decide to keep a '_shrinkmask' option, we want to check that ...
Chris@87 6323 # ... all of them are True, and then check for dm.any()
Chris@87 6324 # shrink = numpy.logical_or.reduce([getattr(a,'_shrinkmask',True) for a in arrays])
Chris@87 6325 # if shrink and not dm.any():
Chris@87 6326 if not dm.dtype.fields and not dm.any():
Chris@87 6327 data._mask = nomask
Chris@87 6328 else:
Chris@87 6329 data._mask = dm.reshape(d.shape)
Chris@87 6330 return data
Chris@87 6331
Chris@87 6332 def count(a, axis=None):
Chris@87 6333 if isinstance(a, MaskedArray):
Chris@87 6334 return a.count(axis)
Chris@87 6335 return masked_array(a, copy=False).count(axis)
Chris@87 6336 count.__doc__ = MaskedArray.count.__doc__
Chris@87 6337
Chris@87 6338
Chris@87 6339 def diag(v, k=0):
Chris@87 6340 """
Chris@87 6341 Extract a diagonal or construct a diagonal array.
Chris@87 6342
Chris@87 6343 This function is the equivalent of `numpy.diag` that takes masked
Chris@87 6344 values into account, see `numpy.diag` for details.
Chris@87 6345
Chris@87 6346 See Also
Chris@87 6347 --------
Chris@87 6348 numpy.diag : Equivalent function for ndarrays.
Chris@87 6349
Chris@87 6350 """
Chris@87 6351 output = np.diag(v, k).view(MaskedArray)
Chris@87 6352 if getmask(v) is not nomask:
Chris@87 6353 output._mask = np.diag(v._mask, k)
Chris@87 6354 return output
Chris@87 6355
Chris@87 6356
Chris@87 6357 def expand_dims(x, axis):
Chris@87 6358 """
Chris@87 6359 Expand the shape of an array.
Chris@87 6360
Chris@87 6361 Expands the shape of the array by including a new axis before the one
Chris@87 6362 specified by the `axis` parameter. This function behaves the same as
Chris@87 6363 `numpy.expand_dims` but preserves masked elements.
Chris@87 6364
Chris@87 6365 See Also
Chris@87 6366 --------
Chris@87 6367 numpy.expand_dims : Equivalent function in top-level NumPy module.
Chris@87 6368
Chris@87 6369 Examples
Chris@87 6370 --------
Chris@87 6371 >>> import numpy.ma as ma
Chris@87 6372 >>> x = ma.array([1, 2, 4])
Chris@87 6373 >>> x[1] = ma.masked
Chris@87 6374 >>> x
Chris@87 6375 masked_array(data = [1 -- 4],
Chris@87 6376 mask = [False True False],
Chris@87 6377 fill_value = 999999)
Chris@87 6378 >>> np.expand_dims(x, axis=0)
Chris@87 6379 array([[1, 2, 4]])
Chris@87 6380 >>> ma.expand_dims(x, axis=0)
Chris@87 6381 masked_array(data =
Chris@87 6382 [[1 -- 4]],
Chris@87 6383 mask =
Chris@87 6384 [[False True False]],
Chris@87 6385 fill_value = 999999)
Chris@87 6386
Chris@87 6387 The same result can be achieved using slicing syntax with `np.newaxis`.
Chris@87 6388
Chris@87 6389 >>> x[np.newaxis, :]
Chris@87 6390 masked_array(data =
Chris@87 6391 [[1 -- 4]],
Chris@87 6392 mask =
Chris@87 6393 [[False True False]],
Chris@87 6394 fill_value = 999999)
Chris@87 6395
Chris@87 6396 """
Chris@87 6397 result = n_expand_dims(x, axis)
Chris@87 6398 if isinstance(x, MaskedArray):
Chris@87 6399 new_shape = result.shape
Chris@87 6400 result = x.view()
Chris@87 6401 result.shape = new_shape
Chris@87 6402 if result._mask is not nomask:
Chris@87 6403 result._mask.shape = new_shape
Chris@87 6404 return result
Chris@87 6405
Chris@87 6406 #......................................
Chris@87 6407 def left_shift (a, n):
Chris@87 6408 """
Chris@87 6409 Shift the bits of an integer to the left.
Chris@87 6410
Chris@87 6411 This is the masked array version of `numpy.left_shift`, for details
Chris@87 6412 see that function.
Chris@87 6413
Chris@87 6414 See Also
Chris@87 6415 --------
Chris@87 6416 numpy.left_shift
Chris@87 6417
Chris@87 6418 """
Chris@87 6419 m = getmask(a)
Chris@87 6420 if m is nomask:
Chris@87 6421 d = umath.left_shift(filled(a), n)
Chris@87 6422 return masked_array(d)
Chris@87 6423 else:
Chris@87 6424 d = umath.left_shift(filled(a, 0), n)
Chris@87 6425 return masked_array(d, mask=m)
Chris@87 6426
Chris@87 6427 def right_shift (a, n):
Chris@87 6428 """
Chris@87 6429 Shift the bits of an integer to the right.
Chris@87 6430
Chris@87 6431 This is the masked array version of `numpy.right_shift`, for details
Chris@87 6432 see that function.
Chris@87 6433
Chris@87 6434 See Also
Chris@87 6435 --------
Chris@87 6436 numpy.right_shift
Chris@87 6437
Chris@87 6438 """
Chris@87 6439 m = getmask(a)
Chris@87 6440 if m is nomask:
Chris@87 6441 d = umath.right_shift(filled(a), n)
Chris@87 6442 return masked_array(d)
Chris@87 6443 else:
Chris@87 6444 d = umath.right_shift(filled(a, 0), n)
Chris@87 6445 return masked_array(d, mask=m)
Chris@87 6446
Chris@87 6447 #......................................
Chris@87 6448 def put(a, indices, values, mode='raise'):
Chris@87 6449 """
Chris@87 6450 Set storage-indexed locations to corresponding values.
Chris@87 6451
Chris@87 6452 This function is equivalent to `MaskedArray.put`, see that method
Chris@87 6453 for details.
Chris@87 6454
Chris@87 6455 See Also
Chris@87 6456 --------
Chris@87 6457 MaskedArray.put
Chris@87 6458
Chris@87 6459 """
Chris@87 6460 # We can't use 'frommethod', the order of arguments is different
Chris@87 6461 try:
Chris@87 6462 return a.put(indices, values, mode=mode)
Chris@87 6463 except AttributeError:
Chris@87 6464 return narray(a, copy=False).put(indices, values, mode=mode)
Chris@87 6465
Chris@87 6466 def putmask(a, mask, values): #, mode='raise'):
Chris@87 6467 """
Chris@87 6468 Changes elements of an array based on conditional and input values.
Chris@87 6469
Chris@87 6470 This is the masked array version of `numpy.putmask`, for details see
Chris@87 6471 `numpy.putmask`.
Chris@87 6472
Chris@87 6473 See Also
Chris@87 6474 --------
Chris@87 6475 numpy.putmask
Chris@87 6476
Chris@87 6477 Notes
Chris@87 6478 -----
Chris@87 6479 Using a masked array as `values` will **not** transform a `ndarray` into
Chris@87 6480 a `MaskedArray`.
Chris@87 6481
Chris@87 6482 """
Chris@87 6483 # We can't use 'frommethod', the order of arguments is different
Chris@87 6484 if not isinstance(a, MaskedArray):
Chris@87 6485 a = a.view(MaskedArray)
Chris@87 6486 (valdata, valmask) = (getdata(values), getmask(values))
Chris@87 6487 if getmask(a) is nomask:
Chris@87 6488 if valmask is not nomask:
Chris@87 6489 a._sharedmask = True
Chris@87 6490 a._mask = make_mask_none(a.shape, a.dtype)
Chris@87 6491 np.copyto(a._mask, valmask, where=mask)
Chris@87 6492 elif a._hardmask:
Chris@87 6493 if valmask is not nomask:
Chris@87 6494 m = a._mask.copy()
Chris@87 6495 np.copyto(m, valmask, where=mask)
Chris@87 6496 a.mask |= m
Chris@87 6497 else:
Chris@87 6498 if valmask is nomask:
Chris@87 6499 valmask = getmaskarray(values)
Chris@87 6500 np.copyto(a._mask, valmask, where=mask)
Chris@87 6501 np.copyto(a._data, valdata, where=mask)
Chris@87 6502 return
Chris@87 6503
Chris@87 6504 def transpose(a, axes=None):
Chris@87 6505 """
Chris@87 6506 Permute the dimensions of an array.
Chris@87 6507
Chris@87 6508 This function is exactly equivalent to `numpy.transpose`.
Chris@87 6509
Chris@87 6510 See Also
Chris@87 6511 --------
Chris@87 6512 numpy.transpose : Equivalent function in top-level NumPy module.
Chris@87 6513
Chris@87 6514 Examples
Chris@87 6515 --------
Chris@87 6516 >>> import numpy.ma as ma
Chris@87 6517 >>> x = ma.arange(4).reshape((2,2))
Chris@87 6518 >>> x[1, 1] = ma.masked
Chris@87 6519 >>>> x
Chris@87 6520 masked_array(data =
Chris@87 6521 [[0 1]
Chris@87 6522 [2 --]],
Chris@87 6523 mask =
Chris@87 6524 [[False False]
Chris@87 6525 [False True]],
Chris@87 6526 fill_value = 999999)
Chris@87 6527 >>> ma.transpose(x)
Chris@87 6528 masked_array(data =
Chris@87 6529 [[0 2]
Chris@87 6530 [1 --]],
Chris@87 6531 mask =
Chris@87 6532 [[False False]
Chris@87 6533 [False True]],
Chris@87 6534 fill_value = 999999)
Chris@87 6535
Chris@87 6536 """
Chris@87 6537 #We can't use 'frommethod', as 'transpose' doesn't take keywords
Chris@87 6538 try:
Chris@87 6539 return a.transpose(axes)
Chris@87 6540 except AttributeError:
Chris@87 6541 return narray(a, copy=False).transpose(axes).view(MaskedArray)
Chris@87 6542
Chris@87 6543 def reshape(a, new_shape, order='C'):
Chris@87 6544 """
Chris@87 6545 Returns an array containing the same data with a new shape.
Chris@87 6546
Chris@87 6547 Refer to `MaskedArray.reshape` for full documentation.
Chris@87 6548
Chris@87 6549 See Also
Chris@87 6550 --------
Chris@87 6551 MaskedArray.reshape : equivalent function
Chris@87 6552
Chris@87 6553 """
Chris@87 6554 #We can't use 'frommethod', it whine about some parameters. Dmmit.
Chris@87 6555 try:
Chris@87 6556 return a.reshape(new_shape, order=order)
Chris@87 6557 except AttributeError:
Chris@87 6558 _tmp = narray(a, copy=False).reshape(new_shape, order=order)
Chris@87 6559 return _tmp.view(MaskedArray)
Chris@87 6560
Chris@87 6561 def resize(x, new_shape):
Chris@87 6562 """
Chris@87 6563 Return a new masked array with the specified size and shape.
Chris@87 6564
Chris@87 6565 This is the masked equivalent of the `numpy.resize` function. The new
Chris@87 6566 array is filled with repeated copies of `x` (in the order that the
Chris@87 6567 data are stored in memory). If `x` is masked, the new array will be
Chris@87 6568 masked, and the new mask will be a repetition of the old one.
Chris@87 6569
Chris@87 6570 See Also
Chris@87 6571 --------
Chris@87 6572 numpy.resize : Equivalent function in the top level NumPy module.
Chris@87 6573
Chris@87 6574 Examples
Chris@87 6575 --------
Chris@87 6576 >>> import numpy.ma as ma
Chris@87 6577 >>> a = ma.array([[1, 2] ,[3, 4]])
Chris@87 6578 >>> a[0, 1] = ma.masked
Chris@87 6579 >>> a
Chris@87 6580 masked_array(data =
Chris@87 6581 [[1 --]
Chris@87 6582 [3 4]],
Chris@87 6583 mask =
Chris@87 6584 [[False True]
Chris@87 6585 [False False]],
Chris@87 6586 fill_value = 999999)
Chris@87 6587 >>> np.resize(a, (3, 3))
Chris@87 6588 array([[1, 2, 3],
Chris@87 6589 [4, 1, 2],
Chris@87 6590 [3, 4, 1]])
Chris@87 6591 >>> ma.resize(a, (3, 3))
Chris@87 6592 masked_array(data =
Chris@87 6593 [[1 -- 3]
Chris@87 6594 [4 1 --]
Chris@87 6595 [3 4 1]],
Chris@87 6596 mask =
Chris@87 6597 [[False True False]
Chris@87 6598 [False False True]
Chris@87 6599 [False False False]],
Chris@87 6600 fill_value = 999999)
Chris@87 6601
Chris@87 6602 A MaskedArray is always returned, regardless of the input type.
Chris@87 6603
Chris@87 6604 >>> a = np.array([[1, 2] ,[3, 4]])
Chris@87 6605 >>> ma.resize(a, (3, 3))
Chris@87 6606 masked_array(data =
Chris@87 6607 [[1 2 3]
Chris@87 6608 [4 1 2]
Chris@87 6609 [3 4 1]],
Chris@87 6610 mask =
Chris@87 6611 False,
Chris@87 6612 fill_value = 999999)
Chris@87 6613
Chris@87 6614 """
Chris@87 6615 # We can't use _frommethods here, as N.resize is notoriously whiny.
Chris@87 6616 m = getmask(x)
Chris@87 6617 if m is not nomask:
Chris@87 6618 m = np.resize(m, new_shape)
Chris@87 6619 result = np.resize(x, new_shape).view(get_masked_subclass(x))
Chris@87 6620 if result.ndim:
Chris@87 6621 result._mask = m
Chris@87 6622 return result
Chris@87 6623
Chris@87 6624
Chris@87 6625 #................................................
Chris@87 6626 def rank(obj):
Chris@87 6627 "maskedarray version of the numpy function."
Chris@87 6628 return np.rank(getdata(obj))
Chris@87 6629 rank.__doc__ = np.rank.__doc__
Chris@87 6630 #
Chris@87 6631 def shape(obj):
Chris@87 6632 "maskedarray version of the numpy function."
Chris@87 6633 return np.shape(getdata(obj))
Chris@87 6634 shape.__doc__ = np.shape.__doc__
Chris@87 6635 #
Chris@87 6636 def size(obj, axis=None):
Chris@87 6637 "maskedarray version of the numpy function."
Chris@87 6638 return np.size(getdata(obj), axis)
Chris@87 6639 size.__doc__ = np.size.__doc__
Chris@87 6640 #................................................
Chris@87 6641
Chris@87 6642 #####--------------------------------------------------------------------------
Chris@87 6643 #---- --- Extra functions ---
Chris@87 6644 #####--------------------------------------------------------------------------
Chris@87 6645 def where (condition, x=None, y=None):
Chris@87 6646 """
Chris@87 6647 Return a masked array with elements from x or y, depending on condition.
Chris@87 6648
Chris@87 6649 Returns a masked array, shaped like condition, where the elements
Chris@87 6650 are from `x` when `condition` is True, and from `y` otherwise.
Chris@87 6651 If neither `x` nor `y` are given, the function returns a tuple of
Chris@87 6652 indices where `condition` is True (the result of
Chris@87 6653 ``condition.nonzero()``).
Chris@87 6654
Chris@87 6655 Parameters
Chris@87 6656 ----------
Chris@87 6657 condition : array_like, bool
Chris@87 6658 The condition to meet. For each True element, yield the corresponding
Chris@87 6659 element from `x`, otherwise from `y`.
Chris@87 6660 x, y : array_like, optional
Chris@87 6661 Values from which to choose. `x` and `y` need to have the same shape
Chris@87 6662 as condition, or be broadcast-able to that shape.
Chris@87 6663
Chris@87 6664 Returns
Chris@87 6665 -------
Chris@87 6666 out : MaskedArray or tuple of ndarrays
Chris@87 6667 The resulting masked array if `x` and `y` were given, otherwise
Chris@87 6668 the result of ``condition.nonzero()``.
Chris@87 6669
Chris@87 6670 See Also
Chris@87 6671 --------
Chris@87 6672 numpy.where : Equivalent function in the top-level NumPy module.
Chris@87 6673
Chris@87 6674 Examples
Chris@87 6675 --------
Chris@87 6676 >>> x = np.ma.array(np.arange(9.).reshape(3, 3), mask=[[0, 1, 0],
Chris@87 6677 ... [1, 0, 1],
Chris@87 6678 ... [0, 1, 0]])
Chris@87 6679 >>> print x
Chris@87 6680 [[0.0 -- 2.0]
Chris@87 6681 [-- 4.0 --]
Chris@87 6682 [6.0 -- 8.0]]
Chris@87 6683 >>> np.ma.where(x > 5) # return the indices where x > 5
Chris@87 6684 (array([2, 2]), array([0, 2]))
Chris@87 6685
Chris@87 6686 >>> print np.ma.where(x > 5, x, -3.1416)
Chris@87 6687 [[-3.1416 -- -3.1416]
Chris@87 6688 [-- -3.1416 --]
Chris@87 6689 [6.0 -- 8.0]]
Chris@87 6690
Chris@87 6691 """
Chris@87 6692 if x is None and y is None:
Chris@87 6693 return filled(condition, 0).nonzero()
Chris@87 6694 elif x is None or y is None:
Chris@87 6695 raise ValueError("Either both or neither x and y should be given.")
Chris@87 6696 # Get the condition ...............
Chris@87 6697 fc = filled(condition, 0).astype(MaskType)
Chris@87 6698 notfc = np.logical_not(fc)
Chris@87 6699 # Get the data ......................................
Chris@87 6700 xv = getdata(x)
Chris@87 6701 yv = getdata(y)
Chris@87 6702 if x is masked:
Chris@87 6703 ndtype = yv.dtype
Chris@87 6704 elif y is masked:
Chris@87 6705 ndtype = xv.dtype
Chris@87 6706 else:
Chris@87 6707 ndtype = np.find_common_type([xv.dtype, yv.dtype], [])
Chris@87 6708 # Construct an empty array and fill it
Chris@87 6709 d = np.empty(fc.shape, dtype=ndtype).view(MaskedArray)
Chris@87 6710 _data = d._data
Chris@87 6711 np.copyto(_data, xv.astype(ndtype), where=fc)
Chris@87 6712 np.copyto(_data, yv.astype(ndtype), where=notfc)
Chris@87 6713 # Create an empty mask and fill it
Chris@87 6714 _mask = d._mask = np.zeros(fc.shape, dtype=MaskType)
Chris@87 6715 np.copyto(_mask, getmask(x), where=fc)
Chris@87 6716 np.copyto(_mask, getmask(y), where=notfc)
Chris@87 6717 _mask |= getmaskarray(condition)
Chris@87 6718 if not _mask.any():
Chris@87 6719 d._mask = nomask
Chris@87 6720 return d
Chris@87 6721
Chris@87 6722 def choose (indices, choices, out=None, mode='raise'):
Chris@87 6723 """
Chris@87 6724 Use an index array to construct a new array from a set of choices.
Chris@87 6725
Chris@87 6726 Given an array of integers and a set of n choice arrays, this method
Chris@87 6727 will create a new array that merges each of the choice arrays. Where a
Chris@87 6728 value in `a` is i, the new array will have the value that choices[i]
Chris@87 6729 contains in the same place.
Chris@87 6730
Chris@87 6731 Parameters
Chris@87 6732 ----------
Chris@87 6733 a : ndarray of ints
Chris@87 6734 This array must contain integers in ``[0, n-1]``, where n is the
Chris@87 6735 number of choices.
Chris@87 6736 choices : sequence of arrays
Chris@87 6737 Choice arrays. The index array and all of the choices should be
Chris@87 6738 broadcastable to the same shape.
Chris@87 6739 out : array, optional
Chris@87 6740 If provided, the result will be inserted into this array. It should
Chris@87 6741 be of the appropriate shape and `dtype`.
Chris@87 6742 mode : {'raise', 'wrap', 'clip'}, optional
Chris@87 6743 Specifies how out-of-bounds indices will behave.
Chris@87 6744
Chris@87 6745 * 'raise' : raise an error
Chris@87 6746 * 'wrap' : wrap around
Chris@87 6747 * 'clip' : clip to the range
Chris@87 6748
Chris@87 6749 Returns
Chris@87 6750 -------
Chris@87 6751 merged_array : array
Chris@87 6752
Chris@87 6753 See Also
Chris@87 6754 --------
Chris@87 6755 choose : equivalent function
Chris@87 6756
Chris@87 6757 Examples
Chris@87 6758 --------
Chris@87 6759 >>> choice = np.array([[1,1,1], [2,2,2], [3,3,3]])
Chris@87 6760 >>> a = np.array([2, 1, 0])
Chris@87 6761 >>> np.ma.choose(a, choice)
Chris@87 6762 masked_array(data = [3 2 1],
Chris@87 6763 mask = False,
Chris@87 6764 fill_value=999999)
Chris@87 6765
Chris@87 6766 """
Chris@87 6767 def fmask (x):
Chris@87 6768 "Returns the filled array, or True if masked."
Chris@87 6769 if x is masked:
Chris@87 6770 return True
Chris@87 6771 return filled(x)
Chris@87 6772 def nmask (x):
Chris@87 6773 "Returns the mask, True if ``masked``, False if ``nomask``."
Chris@87 6774 if x is masked:
Chris@87 6775 return True
Chris@87 6776 return getmask(x)
Chris@87 6777 # Get the indices......
Chris@87 6778 c = filled(indices, 0)
Chris@87 6779 # Get the masks........
Chris@87 6780 masks = [nmask(x) for x in choices]
Chris@87 6781 data = [fmask(x) for x in choices]
Chris@87 6782 # Construct the mask
Chris@87 6783 outputmask = np.choose(c, masks, mode=mode)
Chris@87 6784 outputmask = make_mask(mask_or(outputmask, getmask(indices)),
Chris@87 6785 copy=0, shrink=True)
Chris@87 6786 # Get the choices......
Chris@87 6787 d = np.choose(c, data, mode=mode, out=out).view(MaskedArray)
Chris@87 6788 if out is not None:
Chris@87 6789 if isinstance(out, MaskedArray):
Chris@87 6790 out.__setmask__(outputmask)
Chris@87 6791 return out
Chris@87 6792 d.__setmask__(outputmask)
Chris@87 6793 return d
Chris@87 6794
Chris@87 6795
Chris@87 6796 def round_(a, decimals=0, out=None):
Chris@87 6797 """
Chris@87 6798 Return a copy of a, rounded to 'decimals' places.
Chris@87 6799
Chris@87 6800 When 'decimals' is negative, it specifies the number of positions
Chris@87 6801 to the left of the decimal point. The real and imaginary parts of
Chris@87 6802 complex numbers are rounded separately. Nothing is done if the
Chris@87 6803 array is not of float type and 'decimals' is greater than or equal
Chris@87 6804 to 0.
Chris@87 6805
Chris@87 6806 Parameters
Chris@87 6807 ----------
Chris@87 6808 decimals : int
Chris@87 6809 Number of decimals to round to. May be negative.
Chris@87 6810 out : array_like
Chris@87 6811 Existing array to use for output.
Chris@87 6812 If not given, returns a default copy of a.
Chris@87 6813
Chris@87 6814 Notes
Chris@87 6815 -----
Chris@87 6816 If out is given and does not have a mask attribute, the mask of a
Chris@87 6817 is lost!
Chris@87 6818
Chris@87 6819 """
Chris@87 6820 if out is None:
Chris@87 6821 return np.round_(a, decimals, out)
Chris@87 6822 else:
Chris@87 6823 np.round_(getdata(a), decimals, out)
Chris@87 6824 if hasattr(out, '_mask'):
Chris@87 6825 out._mask = getmask(a)
Chris@87 6826 return out
Chris@87 6827 round = round_
Chris@87 6828
Chris@87 6829 def inner(a, b):
Chris@87 6830 """
Chris@87 6831 Returns the inner product of a and b for arrays of floating point types.
Chris@87 6832
Chris@87 6833 Like the generic NumPy equivalent the product sum is over the last dimension
Chris@87 6834 of a and b.
Chris@87 6835
Chris@87 6836 Notes
Chris@87 6837 -----
Chris@87 6838 The first argument is not conjugated.
Chris@87 6839
Chris@87 6840 """
Chris@87 6841 fa = filled(a, 0)
Chris@87 6842 fb = filled(b, 0)
Chris@87 6843 if len(fa.shape) == 0:
Chris@87 6844 fa.shape = (1,)
Chris@87 6845 if len(fb.shape) == 0:
Chris@87 6846 fb.shape = (1,)
Chris@87 6847 return np.inner(fa, fb).view(MaskedArray)
Chris@87 6848 inner.__doc__ = doc_note(np.inner.__doc__,
Chris@87 6849 "Masked values are replaced by 0.")
Chris@87 6850 innerproduct = inner
Chris@87 6851
Chris@87 6852 def outer(a, b):
Chris@87 6853 "maskedarray version of the numpy function."
Chris@87 6854 fa = filled(a, 0).ravel()
Chris@87 6855 fb = filled(b, 0).ravel()
Chris@87 6856 d = np.outer(fa, fb)
Chris@87 6857 ma = getmask(a)
Chris@87 6858 mb = getmask(b)
Chris@87 6859 if ma is nomask and mb is nomask:
Chris@87 6860 return masked_array(d)
Chris@87 6861 ma = getmaskarray(a)
Chris@87 6862 mb = getmaskarray(b)
Chris@87 6863 m = make_mask(1 - np.outer(1 - ma, 1 - mb), copy=0)
Chris@87 6864 return masked_array(d, mask=m)
Chris@87 6865 outer.__doc__ = doc_note(np.outer.__doc__,
Chris@87 6866 "Masked values are replaced by 0.")
Chris@87 6867 outerproduct = outer
Chris@87 6868
Chris@87 6869 def allequal (a, b, fill_value=True):
Chris@87 6870 """
Chris@87 6871 Return True if all entries of a and b are equal, using
Chris@87 6872 fill_value as a truth value where either or both are masked.
Chris@87 6873
Chris@87 6874 Parameters
Chris@87 6875 ----------
Chris@87 6876 a, b : array_like
Chris@87 6877 Input arrays to compare.
Chris@87 6878 fill_value : bool, optional
Chris@87 6879 Whether masked values in a or b are considered equal (True) or not
Chris@87 6880 (False).
Chris@87 6881
Chris@87 6882 Returns
Chris@87 6883 -------
Chris@87 6884 y : bool
Chris@87 6885 Returns True if the two arrays are equal within the given
Chris@87 6886 tolerance, False otherwise. If either array contains NaN,
Chris@87 6887 then False is returned.
Chris@87 6888
Chris@87 6889 See Also
Chris@87 6890 --------
Chris@87 6891 all, any
Chris@87 6892 numpy.ma.allclose
Chris@87 6893
Chris@87 6894 Examples
Chris@87 6895 --------
Chris@87 6896 >>> a = ma.array([1e10, 1e-7, 42.0], mask=[0, 0, 1])
Chris@87 6897 >>> a
Chris@87 6898 masked_array(data = [10000000000.0 1e-07 --],
Chris@87 6899 mask = [False False True],
Chris@87 6900 fill_value=1e+20)
Chris@87 6901
Chris@87 6902 >>> b = array([1e10, 1e-7, -42.0])
Chris@87 6903 >>> b
Chris@87 6904 array([ 1.00000000e+10, 1.00000000e-07, -4.20000000e+01])
Chris@87 6905 >>> ma.allequal(a, b, fill_value=False)
Chris@87 6906 False
Chris@87 6907 >>> ma.allequal(a, b)
Chris@87 6908 True
Chris@87 6909
Chris@87 6910 """
Chris@87 6911 m = mask_or(getmask(a), getmask(b))
Chris@87 6912 if m is nomask:
Chris@87 6913 x = getdata(a)
Chris@87 6914 y = getdata(b)
Chris@87 6915 d = umath.equal(x, y)
Chris@87 6916 return d.all()
Chris@87 6917 elif fill_value:
Chris@87 6918 x = getdata(a)
Chris@87 6919 y = getdata(b)
Chris@87 6920 d = umath.equal(x, y)
Chris@87 6921 dm = array(d, mask=m, copy=False)
Chris@87 6922 return dm.filled(True).all(None)
Chris@87 6923 else:
Chris@87 6924 return False
Chris@87 6925
Chris@87 6926 def allclose (a, b, masked_equal=True, rtol=1e-5, atol=1e-8):
Chris@87 6927 """
Chris@87 6928 Returns True if two arrays are element-wise equal within a tolerance.
Chris@87 6929
Chris@87 6930 This function is equivalent to `allclose` except that masked values
Chris@87 6931 are treated as equal (default) or unequal, depending on the `masked_equal`
Chris@87 6932 argument.
Chris@87 6933
Chris@87 6934 Parameters
Chris@87 6935 ----------
Chris@87 6936 a, b : array_like
Chris@87 6937 Input arrays to compare.
Chris@87 6938 masked_equal : bool, optional
Chris@87 6939 Whether masked values in `a` and `b` are considered equal (True) or not
Chris@87 6940 (False). They are considered equal by default.
Chris@87 6941 rtol : float, optional
Chris@87 6942 Relative tolerance. The relative difference is equal to ``rtol * b``.
Chris@87 6943 Default is 1e-5.
Chris@87 6944 atol : float, optional
Chris@87 6945 Absolute tolerance. The absolute difference is equal to `atol`.
Chris@87 6946 Default is 1e-8.
Chris@87 6947
Chris@87 6948 Returns
Chris@87 6949 -------
Chris@87 6950 y : bool
Chris@87 6951 Returns True if the two arrays are equal within the given
Chris@87 6952 tolerance, False otherwise. If either array contains NaN, then
Chris@87 6953 False is returned.
Chris@87 6954
Chris@87 6955 See Also
Chris@87 6956 --------
Chris@87 6957 all, any
Chris@87 6958 numpy.allclose : the non-masked `allclose`.
Chris@87 6959
Chris@87 6960 Notes
Chris@87 6961 -----
Chris@87 6962 If the following equation is element-wise True, then `allclose` returns
Chris@87 6963 True::
Chris@87 6964
Chris@87 6965 absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`))
Chris@87 6966
Chris@87 6967 Return True if all elements of `a` and `b` are equal subject to
Chris@87 6968 given tolerances.
Chris@87 6969
Chris@87 6970 Examples
Chris@87 6971 --------
Chris@87 6972 >>> a = ma.array([1e10, 1e-7, 42.0], mask=[0, 0, 1])
Chris@87 6973 >>> a
Chris@87 6974 masked_array(data = [10000000000.0 1e-07 --],
Chris@87 6975 mask = [False False True],
Chris@87 6976 fill_value = 1e+20)
Chris@87 6977 >>> b = ma.array([1e10, 1e-8, -42.0], mask=[0, 0, 1])
Chris@87 6978 >>> ma.allclose(a, b)
Chris@87 6979 False
Chris@87 6980
Chris@87 6981 >>> a = ma.array([1e10, 1e-8, 42.0], mask=[0, 0, 1])
Chris@87 6982 >>> b = ma.array([1.00001e10, 1e-9, -42.0], mask=[0, 0, 1])
Chris@87 6983 >>> ma.allclose(a, b)
Chris@87 6984 True
Chris@87 6985 >>> ma.allclose(a, b, masked_equal=False)
Chris@87 6986 False
Chris@87 6987
Chris@87 6988 Masked values are not compared directly.
Chris@87 6989
Chris@87 6990 >>> a = ma.array([1e10, 1e-8, 42.0], mask=[0, 0, 1])
Chris@87 6991 >>> b = ma.array([1.00001e10, 1e-9, 42.0], mask=[0, 0, 1])
Chris@87 6992 >>> ma.allclose(a, b)
Chris@87 6993 True
Chris@87 6994 >>> ma.allclose(a, b, masked_equal=False)
Chris@87 6995 False
Chris@87 6996
Chris@87 6997 """
Chris@87 6998 x = masked_array(a, copy=False)
Chris@87 6999 y = masked_array(b, copy=False)
Chris@87 7000
Chris@87 7001 # make sure y is an inexact type to avoid abs(MIN_INT); will cause
Chris@87 7002 # casting of x later.
Chris@87 7003 dtype = np.result_type(y, 1.)
Chris@87 7004 if y.dtype != dtype:
Chris@87 7005 y = masked_array(y, dtype=dtype, copy=False)
Chris@87 7006
Chris@87 7007 m = mask_or(getmask(x), getmask(y))
Chris@87 7008 xinf = np.isinf(masked_array(x, copy=False, mask=m)).filled(False)
Chris@87 7009 # If we have some infs, they should fall at the same place.
Chris@87 7010 if not np.all(xinf == filled(np.isinf(y), False)):
Chris@87 7011 return False
Chris@87 7012 # No infs at all
Chris@87 7013 if not np.any(xinf):
Chris@87 7014 d = filled(umath.less_equal(umath.absolute(x - y),
Chris@87 7015 atol + rtol * umath.absolute(y)),
Chris@87 7016 masked_equal)
Chris@87 7017 return np.all(d)
Chris@87 7018
Chris@87 7019 if not np.all(filled(x[xinf] == y[xinf], masked_equal)):
Chris@87 7020 return False
Chris@87 7021 x = x[~xinf]
Chris@87 7022 y = y[~xinf]
Chris@87 7023
Chris@87 7024 d = filled(umath.less_equal(umath.absolute(x - y),
Chris@87 7025 atol + rtol * umath.absolute(y)),
Chris@87 7026 masked_equal)
Chris@87 7027
Chris@87 7028 return np.all(d)
Chris@87 7029
Chris@87 7030 #..............................................................................
Chris@87 7031 def asarray(a, dtype=None, order=None):
Chris@87 7032 """
Chris@87 7033 Convert the input to a masked array of the given data-type.
Chris@87 7034
Chris@87 7035 No copy is performed if the input is already an `ndarray`. If `a` is
Chris@87 7036 a subclass of `MaskedArray`, a base class `MaskedArray` is returned.
Chris@87 7037
Chris@87 7038 Parameters
Chris@87 7039 ----------
Chris@87 7040 a : array_like
Chris@87 7041 Input data, in any form that can be converted to a masked array. This
Chris@87 7042 includes lists, lists of tuples, tuples, tuples of tuples, tuples
Chris@87 7043 of lists, ndarrays and masked arrays.
Chris@87 7044 dtype : dtype, optional
Chris@87 7045 By default, the data-type is inferred from the input data.
Chris@87 7046 order : {'C', 'F'}, optional
Chris@87 7047 Whether to use row-major ('C') or column-major ('FORTRAN') memory
Chris@87 7048 representation. Default is 'C'.
Chris@87 7049
Chris@87 7050 Returns
Chris@87 7051 -------
Chris@87 7052 out : MaskedArray
Chris@87 7053 Masked array interpretation of `a`.
Chris@87 7054
Chris@87 7055 See Also
Chris@87 7056 --------
Chris@87 7057 asanyarray : Similar to `asarray`, but conserves subclasses.
Chris@87 7058
Chris@87 7059 Examples
Chris@87 7060 --------
Chris@87 7061 >>> x = np.arange(10.).reshape(2, 5)
Chris@87 7062 >>> x
Chris@87 7063 array([[ 0., 1., 2., 3., 4.],
Chris@87 7064 [ 5., 6., 7., 8., 9.]])
Chris@87 7065 >>> np.ma.asarray(x)
Chris@87 7066 masked_array(data =
Chris@87 7067 [[ 0. 1. 2. 3. 4.]
Chris@87 7068 [ 5. 6. 7. 8. 9.]],
Chris@87 7069 mask =
Chris@87 7070 False,
Chris@87 7071 fill_value = 1e+20)
Chris@87 7072 >>> type(np.ma.asarray(x))
Chris@87 7073 <class 'numpy.ma.core.MaskedArray'>
Chris@87 7074
Chris@87 7075 """
Chris@87 7076 return masked_array(a, dtype=dtype, copy=False, keep_mask=True, subok=False)
Chris@87 7077
Chris@87 7078 def asanyarray(a, dtype=None):
Chris@87 7079 """
Chris@87 7080 Convert the input to a masked array, conserving subclasses.
Chris@87 7081
Chris@87 7082 If `a` is a subclass of `MaskedArray`, its class is conserved.
Chris@87 7083 No copy is performed if the input is already an `ndarray`.
Chris@87 7084
Chris@87 7085 Parameters
Chris@87 7086 ----------
Chris@87 7087 a : array_like
Chris@87 7088 Input data, in any form that can be converted to an array.
Chris@87 7089 dtype : dtype, optional
Chris@87 7090 By default, the data-type is inferred from the input data.
Chris@87 7091 order : {'C', 'F'}, optional
Chris@87 7092 Whether to use row-major ('C') or column-major ('FORTRAN') memory
Chris@87 7093 representation. Default is 'C'.
Chris@87 7094
Chris@87 7095 Returns
Chris@87 7096 -------
Chris@87 7097 out : MaskedArray
Chris@87 7098 MaskedArray interpretation of `a`.
Chris@87 7099
Chris@87 7100 See Also
Chris@87 7101 --------
Chris@87 7102 asarray : Similar to `asanyarray`, but does not conserve subclass.
Chris@87 7103
Chris@87 7104 Examples
Chris@87 7105 --------
Chris@87 7106 >>> x = np.arange(10.).reshape(2, 5)
Chris@87 7107 >>> x
Chris@87 7108 array([[ 0., 1., 2., 3., 4.],
Chris@87 7109 [ 5., 6., 7., 8., 9.]])
Chris@87 7110 >>> np.ma.asanyarray(x)
Chris@87 7111 masked_array(data =
Chris@87 7112 [[ 0. 1. 2. 3. 4.]
Chris@87 7113 [ 5. 6. 7. 8. 9.]],
Chris@87 7114 mask =
Chris@87 7115 False,
Chris@87 7116 fill_value = 1e+20)
Chris@87 7117 >>> type(np.ma.asanyarray(x))
Chris@87 7118 <class 'numpy.ma.core.MaskedArray'>
Chris@87 7119
Chris@87 7120 """
Chris@87 7121 return masked_array(a, dtype=dtype, copy=False, keep_mask=True, subok=True)
Chris@87 7122
Chris@87 7123
Chris@87 7124 #####--------------------------------------------------------------------------
Chris@87 7125 #---- --- Pickling ---
Chris@87 7126 #####--------------------------------------------------------------------------
Chris@87 7127 def dump(a, F):
Chris@87 7128 """
Chris@87 7129 Pickle a masked array to a file.
Chris@87 7130
Chris@87 7131 This is a wrapper around ``cPickle.dump``.
Chris@87 7132
Chris@87 7133 Parameters
Chris@87 7134 ----------
Chris@87 7135 a : MaskedArray
Chris@87 7136 The array to be pickled.
Chris@87 7137 F : str or file-like object
Chris@87 7138 The file to pickle `a` to. If a string, the full path to the file.
Chris@87 7139
Chris@87 7140 """
Chris@87 7141 if not hasattr(F, 'readline'):
Chris@87 7142 F = open(F, 'w')
Chris@87 7143 return pickle.dump(a, F)
Chris@87 7144
Chris@87 7145 def dumps(a):
Chris@87 7146 """
Chris@87 7147 Return a string corresponding to the pickling of a masked array.
Chris@87 7148
Chris@87 7149 This is a wrapper around ``cPickle.dumps``.
Chris@87 7150
Chris@87 7151 Parameters
Chris@87 7152 ----------
Chris@87 7153 a : MaskedArray
Chris@87 7154 The array for which the string representation of the pickle is
Chris@87 7155 returned.
Chris@87 7156
Chris@87 7157 """
Chris@87 7158 return pickle.dumps(a)
Chris@87 7159
Chris@87 7160 def load(F):
Chris@87 7161 """
Chris@87 7162 Wrapper around ``cPickle.load`` which accepts either a file-like object
Chris@87 7163 or a filename.
Chris@87 7164
Chris@87 7165 Parameters
Chris@87 7166 ----------
Chris@87 7167 F : str or file
Chris@87 7168 The file or file name to load.
Chris@87 7169
Chris@87 7170 See Also
Chris@87 7171 --------
Chris@87 7172 dump : Pickle an array
Chris@87 7173
Chris@87 7174 Notes
Chris@87 7175 -----
Chris@87 7176 This is different from `numpy.load`, which does not use cPickle but loads
Chris@87 7177 the NumPy binary .npy format.
Chris@87 7178
Chris@87 7179 """
Chris@87 7180 if not hasattr(F, 'readline'):
Chris@87 7181 F = open(F, 'r')
Chris@87 7182 return pickle.load(F)
Chris@87 7183
Chris@87 7184 def loads(strg):
Chris@87 7185 """
Chris@87 7186 Load a pickle from the current string.
Chris@87 7187
Chris@87 7188 The result of ``cPickle.loads(strg)`` is returned.
Chris@87 7189
Chris@87 7190 Parameters
Chris@87 7191 ----------
Chris@87 7192 strg : str
Chris@87 7193 The string to load.
Chris@87 7194
Chris@87 7195 See Also
Chris@87 7196 --------
Chris@87 7197 dumps : Return a string corresponding to the pickling of a masked array.
Chris@87 7198
Chris@87 7199 """
Chris@87 7200 return pickle.loads(strg)
Chris@87 7201
Chris@87 7202 ################################################################################
Chris@87 7203 def fromfile(file, dtype=float, count= -1, sep=''):
Chris@87 7204 raise NotImplementedError("Not yet implemented. Sorry")
Chris@87 7205
Chris@87 7206
Chris@87 7207 def fromflex(fxarray):
Chris@87 7208 """
Chris@87 7209 Build a masked array from a suitable flexible-type array.
Chris@87 7210
Chris@87 7211 The input array has to have a data-type with ``_data`` and ``_mask``
Chris@87 7212 fields. This type of array is output by `MaskedArray.toflex`.
Chris@87 7213
Chris@87 7214 Parameters
Chris@87 7215 ----------
Chris@87 7216 fxarray : ndarray
Chris@87 7217 The structured input array, containing ``_data`` and ``_mask``
Chris@87 7218 fields. If present, other fields are discarded.
Chris@87 7219
Chris@87 7220 Returns
Chris@87 7221 -------
Chris@87 7222 result : MaskedArray
Chris@87 7223 The constructed masked array.
Chris@87 7224
Chris@87 7225 See Also
Chris@87 7226 --------
Chris@87 7227 MaskedArray.toflex : Build a flexible-type array from a masked array.
Chris@87 7228
Chris@87 7229 Examples
Chris@87 7230 --------
Chris@87 7231 >>> x = np.ma.array(np.arange(9).reshape(3, 3), mask=[0] + [1, 0] * 4)
Chris@87 7232 >>> rec = x.toflex()
Chris@87 7233 >>> rec
Chris@87 7234 array([[(0, False), (1, True), (2, False)],
Chris@87 7235 [(3, True), (4, False), (5, True)],
Chris@87 7236 [(6, False), (7, True), (8, False)]],
Chris@87 7237 dtype=[('_data', '<i4'), ('_mask', '|b1')])
Chris@87 7238 >>> x2 = np.ma.fromflex(rec)
Chris@87 7239 >>> x2
Chris@87 7240 masked_array(data =
Chris@87 7241 [[0 -- 2]
Chris@87 7242 [-- 4 --]
Chris@87 7243 [6 -- 8]],
Chris@87 7244 mask =
Chris@87 7245 [[False True False]
Chris@87 7246 [ True False True]
Chris@87 7247 [False True False]],
Chris@87 7248 fill_value = 999999)
Chris@87 7249
Chris@87 7250 Extra fields can be present in the structured array but are discarded:
Chris@87 7251
Chris@87 7252 >>> dt = [('_data', '<i4'), ('_mask', '|b1'), ('field3', '<f4')]
Chris@87 7253 >>> rec2 = np.zeros((2, 2), dtype=dt)
Chris@87 7254 >>> rec2
Chris@87 7255 array([[(0, False, 0.0), (0, False, 0.0)],
Chris@87 7256 [(0, False, 0.0), (0, False, 0.0)]],
Chris@87 7257 dtype=[('_data', '<i4'), ('_mask', '|b1'), ('field3', '<f4')])
Chris@87 7258 >>> y = np.ma.fromflex(rec2)
Chris@87 7259 >>> y
Chris@87 7260 masked_array(data =
Chris@87 7261 [[0 0]
Chris@87 7262 [0 0]],
Chris@87 7263 mask =
Chris@87 7264 [[False False]
Chris@87 7265 [False False]],
Chris@87 7266 fill_value = 999999)
Chris@87 7267
Chris@87 7268 """
Chris@87 7269 return masked_array(fxarray['_data'], mask=fxarray['_mask'])
Chris@87 7270
Chris@87 7271
Chris@87 7272
Chris@87 7273 class _convert2ma:
Chris@87 7274 """
Chris@87 7275 Convert functions from numpy to numpy.ma.
Chris@87 7276
Chris@87 7277 Parameters
Chris@87 7278 ----------
Chris@87 7279 _methodname : string
Chris@87 7280 Name of the method to transform.
Chris@87 7281
Chris@87 7282 """
Chris@87 7283 __doc__ = None
Chris@87 7284 #
Chris@87 7285 def __init__(self, funcname, params=None):
Chris@87 7286 self._func = getattr(np, funcname)
Chris@87 7287 self.__doc__ = self.getdoc()
Chris@87 7288 self._extras = params or {}
Chris@87 7289 #
Chris@87 7290 def getdoc(self):
Chris@87 7291 "Return the doc of the function (from the doc of the method)."
Chris@87 7292 doc = getattr(self._func, '__doc__', None)
Chris@87 7293 sig = get_object_signature(self._func)
Chris@87 7294 if doc:
Chris@87 7295 # Add the signature of the function at the beginning of the doc
Chris@87 7296 if sig:
Chris@87 7297 sig = "%s%s\n" % (self._func.__name__, sig)
Chris@87 7298 doc = sig + doc
Chris@87 7299 return doc
Chris@87 7300 #
Chris@87 7301 def __call__(self, a, *args, **params):
Chris@87 7302 # Find the common parameters to the call and the definition
Chris@87 7303 _extras = self._extras
Chris@87 7304 common_params = set(params).intersection(_extras)
Chris@87 7305 # Drop the common parameters from the call
Chris@87 7306 for p in common_params:
Chris@87 7307 _extras[p] = params.pop(p)
Chris@87 7308 # Get the result
Chris@87 7309 result = self._func.__call__(a, *args, **params).view(MaskedArray)
Chris@87 7310 if "fill_value" in common_params:
Chris@87 7311 result.fill_value = _extras.get("fill_value", None)
Chris@87 7312 if "hardmask" in common_params:
Chris@87 7313 result._hardmask = bool(_extras.get("hard_mask", False))
Chris@87 7314 return result
Chris@87 7315
Chris@87 7316 arange = _convert2ma('arange', params=dict(fill_value=None, hardmask=False))
Chris@87 7317 clip = np.clip
Chris@87 7318 diff = np.diff
Chris@87 7319 empty = _convert2ma('empty', params=dict(fill_value=None, hardmask=False))
Chris@87 7320 empty_like = _convert2ma('empty_like')
Chris@87 7321 frombuffer = _convert2ma('frombuffer')
Chris@87 7322 fromfunction = _convert2ma('fromfunction')
Chris@87 7323 identity = _convert2ma('identity', params=dict(fill_value=None, hardmask=False))
Chris@87 7324 indices = np.indices
Chris@87 7325 ones = _convert2ma('ones', params=dict(fill_value=None, hardmask=False))
Chris@87 7326 ones_like = np.ones_like
Chris@87 7327 squeeze = np.squeeze
Chris@87 7328 zeros = _convert2ma('zeros', params=dict(fill_value=None, hardmask=False))
Chris@87 7329 zeros_like = np.zeros_like
Chris@87 7330
Chris@87 7331 ###############################################################################
Chris@87 7332 def append(a, b, axis=None):
Chris@87 7333 """Append values to the end of an array.
Chris@87 7334
Chris@87 7335 .. versionadded:: 1.9.0
Chris@87 7336
Chris@87 7337 Parameters
Chris@87 7338 ----------
Chris@87 7339 arr : array_like
Chris@87 7340 Values are appended to a copy of this array.
Chris@87 7341 values : array_like
Chris@87 7342 These values are appended to a copy of `arr`. It must be of the
Chris@87 7343 correct shape (the same shape as `arr`, excluding `axis`). If `axis`
Chris@87 7344 is not specified, `values` can be any shape and will be flattened
Chris@87 7345 before use.
Chris@87 7346 axis : int, optional
Chris@87 7347 The axis along which `values` are appended. If `axis` is not given,
Chris@87 7348 both `arr` and `values` are flattened before use.
Chris@87 7349
Chris@87 7350 Returns
Chris@87 7351 -------
Chris@87 7352 append : MaskedArray
Chris@87 7353 A copy of `arr` with `values` appended to `axis`. Note that `append`
Chris@87 7354 does not occur in-place: a new array is allocated and filled. If
Chris@87 7355 `axis` is None, the result is a flattened array.
Chris@87 7356
Chris@87 7357 See Also
Chris@87 7358 --------
Chris@87 7359 numpy.append : Equivalent function in the top-level NumPy module.
Chris@87 7360
Chris@87 7361 Examples
Chris@87 7362 --------
Chris@87 7363 >>> import numpy.ma as ma
Chris@87 7364 >>> a = ma.masked_values([1, 2, 3], 2)
Chris@87 7365 >>> b = ma.masked_values([[4, 5, 6], [7, 8, 9]], 7)
Chris@87 7366 >>> print(ma.append(a, b))
Chris@87 7367 [1 -- 3 4 5 6 -- 8 9]
Chris@87 7368 """
Chris@87 7369 return concatenate([a, b], axis)