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)
|