Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
numpy
GitHub Repository: numpy/numpy
Path: blob/main/numpy/ma/tests/test_core.py
2088 views
1
"""Tests suite for MaskedArray & subclassing.
2
3
:author: Pierre Gerard-Marchant
4
:contact: pierregm_at_uga_dot_edu
5
"""
6
__author__ = "Pierre GF Gerard-Marchant"
7
8
import copy
9
import itertools
10
import operator
11
import pickle
12
import sys
13
import textwrap
14
import warnings
15
from functools import reduce
16
17
import pytest
18
19
import numpy as np
20
import numpy._core.fromnumeric as fromnumeric
21
import numpy._core.umath as umath
22
import numpy.ma.core
23
from numpy import ndarray
24
from numpy._utils import asbytes
25
from numpy.exceptions import AxisError
26
from numpy.ma.core import (
27
MAError,
28
MaskedArray,
29
MaskError,
30
MaskType,
31
abs,
32
absolute,
33
add,
34
all,
35
allclose,
36
allequal,
37
alltrue,
38
angle,
39
anom,
40
arange,
41
arccos,
42
arccosh,
43
arcsin,
44
arctan,
45
arctan2,
46
argsort,
47
array,
48
asarray,
49
choose,
50
concatenate,
51
conjugate,
52
cos,
53
cosh,
54
count,
55
default_fill_value,
56
diag,
57
divide,
58
empty,
59
empty_like,
60
equal,
61
exp,
62
filled,
63
fix_invalid,
64
flatten_mask,
65
flatten_structured_array,
66
fromflex,
67
getmask,
68
getmaskarray,
69
greater,
70
greater_equal,
71
identity,
72
inner,
73
isMaskedArray,
74
less,
75
less_equal,
76
log,
77
log10,
78
make_mask,
79
make_mask_descr,
80
mask_or,
81
masked,
82
masked_array,
83
masked_equal,
84
masked_greater,
85
masked_greater_equal,
86
masked_inside,
87
masked_less,
88
masked_less_equal,
89
masked_not_equal,
90
masked_outside,
91
masked_print_option,
92
masked_values,
93
masked_where,
94
max,
95
maximum,
96
maximum_fill_value,
97
min,
98
minimum,
99
minimum_fill_value,
100
mod,
101
multiply,
102
mvoid,
103
nomask,
104
not_equal,
105
ones,
106
ones_like,
107
outer,
108
power,
109
product,
110
put,
111
putmask,
112
ravel,
113
repeat,
114
reshape,
115
resize,
116
shape,
117
sin,
118
sinh,
119
sometrue,
120
sort,
121
sqrt,
122
subtract,
123
sum,
124
take,
125
tan,
126
tanh,
127
transpose,
128
where,
129
zeros,
130
zeros_like,
131
)
132
from numpy.ma.testutils import (
133
assert_,
134
assert_almost_equal,
135
assert_array_equal,
136
assert_equal,
137
assert_equal_records,
138
assert_mask_equal,
139
assert_not_equal,
140
fail_if_equal,
141
)
142
from numpy.testing import IS_WASM, assert_raises, temppath
143
from numpy.testing._private.utils import requires_memory
144
145
pi = np.pi
146
147
148
# For parametrized numeric testing
149
num_dts = [np.dtype(dt_) for dt_ in '?bhilqBHILQefdgFD']
150
num_ids = [dt_.char for dt_ in num_dts]
151
152
WARNING_MESSAGE = ("setting an item on a masked array which has a shared "
153
"mask will not copy")
154
WARNING_MARK_SPEC = f"ignore:.*{WARNING_MESSAGE}:numpy.ma.core.MaskedArrayFutureWarning"
155
class TestMaskedArray:
156
# Base test class for MaskedArrays.
157
158
# message for warning filters
159
def _create_data(self):
160
# Base data definition.
161
x = np.array([1., 1., 1., -2., pi / 2.0, 4., 5., -10., 10., 1., 2., 3.])
162
y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
163
a10 = 10.
164
m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
165
m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
166
xm = masked_array(x, mask=m1)
167
ym = masked_array(y, mask=m2)
168
z = np.array([-.5, 0., .5, .8])
169
zm = masked_array(z, mask=[0, 1, 0, 0])
170
xf = np.where(m1, 1e+20, x)
171
xm.set_fill_value(1e+20)
172
return x, y, a10, m1, m2, xm, ym, z, zm, xf
173
174
def test_basicattributes(self):
175
# Tests some basic array attributes.
176
a = array([1, 3, 2])
177
b = array([1, 3, 2], mask=[1, 0, 1])
178
assert_equal(a.ndim, 1)
179
assert_equal(b.ndim, 1)
180
assert_equal(a.size, 3)
181
assert_equal(b.size, 3)
182
assert_equal(a.shape, (3,))
183
assert_equal(b.shape, (3,))
184
185
def test_basic0d(self):
186
# Checks masking a scalar
187
x = masked_array(0)
188
assert_equal(str(x), '0')
189
x = masked_array(0, mask=True)
190
assert_equal(str(x), str(masked_print_option))
191
x = masked_array(0, mask=False)
192
assert_equal(str(x), '0')
193
x = array(0, mask=1)
194
assert_(x.filled().dtype is x._data.dtype)
195
196
def test_basic1d(self):
197
# Test of basic array creation and properties in 1 dimension.
198
x, _, _, m1, _, xm, ym, z, zm, xf = self._create_data()
199
assert_(not isMaskedArray(x))
200
assert_(isMaskedArray(xm))
201
assert_((xm - ym).filled(0).any())
202
fail_if_equal(xm.mask.astype(int), ym.mask.astype(int))
203
s = x.shape
204
assert_equal(np.shape(xm), s)
205
assert_equal(xm.shape, s)
206
assert_equal(xm.dtype, x.dtype)
207
assert_equal(zm.dtype, z.dtype)
208
assert_equal(xm.size, reduce(lambda x, y: x * y, s))
209
assert_equal(count(xm), len(m1) - reduce(lambda x, y: x + y, m1))
210
assert_array_equal(xm, xf)
211
assert_array_equal(filled(xm, 1.e20), xf)
212
assert_array_equal(x, xm)
213
214
def test_basic2d(self):
215
# Test of basic array creation and properties in 2 dimensions.
216
x, y, _, m1, _, xm, ym, _, _, xf = self._create_data()
217
for s in [(4, 3), (6, 2)]:
218
x = x.reshape(s)
219
y = y.reshape(s)
220
xm = xm.reshape(s)
221
ym = ym.reshape(s)
222
xf = xf.reshape(s)
223
224
assert_(not isMaskedArray(x))
225
assert_(isMaskedArray(xm))
226
assert_equal(shape(xm), s)
227
assert_equal(xm.shape, s)
228
assert_equal(xm.size, reduce(lambda x, y: x * y, s))
229
assert_equal(count(xm), len(m1) - reduce(lambda x, y: x + y, m1))
230
assert_equal(xm, xf)
231
assert_equal(filled(xm, 1.e20), xf)
232
assert_equal(x, xm)
233
234
def test_concatenate_basic(self):
235
# Tests concatenations.
236
x, y, _, _, _, xm, ym, _, _, _ = self._create_data()
237
# basic concatenation
238
assert_equal(np.concatenate((x, y)), concatenate((xm, ym)))
239
assert_equal(np.concatenate((x, y)), concatenate((x, y)))
240
assert_equal(np.concatenate((x, y)), concatenate((xm, y)))
241
assert_equal(np.concatenate((x, y, x)), concatenate((x, ym, x)))
242
243
def test_concatenate_alongaxis(self):
244
# Tests concatenations.
245
x, y, _, m1, m2, xm, ym, z, _, xf = self._create_data()
246
# Concatenation along an axis
247
s = (3, 4)
248
x = x.reshape(s)
249
y = y.reshape(s)
250
xm = xm.reshape(s)
251
ym = ym.reshape(s)
252
xf = xf.reshape(s)
253
254
assert_equal(xm.mask, np.reshape(m1, s))
255
assert_equal(ym.mask, np.reshape(m2, s))
256
xmym = concatenate((xm, ym), 1)
257
assert_equal(np.concatenate((x, y), 1), xmym)
258
assert_equal(np.concatenate((xm.mask, ym.mask), 1), xmym._mask)
259
260
x = zeros(2)
261
y = array(ones(2), mask=[False, True])
262
z = concatenate((x, y))
263
assert_array_equal(z, [0, 0, 1, 1])
264
assert_array_equal(z.mask, [False, False, False, True])
265
z = concatenate((y, x))
266
assert_array_equal(z, [1, 1, 0, 0])
267
assert_array_equal(z.mask, [False, True, False, False])
268
269
def test_concatenate_flexible(self):
270
# Tests the concatenation on flexible arrays.
271
data = masked_array(list(zip(np.random.rand(10),
272
np.arange(10))),
273
dtype=[('a', float), ('b', int)])
274
275
test = concatenate([data[:5], data[5:]])
276
assert_equal_records(test, data)
277
278
def test_creation_ndmin(self):
279
# Check the use of ndmin
280
x = array([1, 2, 3], mask=[1, 0, 0], ndmin=2)
281
assert_equal(x.shape, (1, 3))
282
assert_equal(x._data, [[1, 2, 3]])
283
assert_equal(x._mask, [[1, 0, 0]])
284
285
def test_creation_ndmin_from_maskedarray(self):
286
# Make sure we're not losing the original mask w/ ndmin
287
x = array([1, 2, 3])
288
x[-1] = masked
289
xx = array(x, ndmin=2, dtype=float)
290
assert_equal(x.shape, x._mask.shape)
291
assert_equal(xx.shape, xx._mask.shape)
292
293
def test_creation_maskcreation(self):
294
# Tests how masks are initialized at the creation of Maskedarrays.
295
data = arange(24, dtype=float)
296
data[[3, 6, 15]] = masked
297
dma_1 = MaskedArray(data)
298
assert_equal(dma_1.mask, data.mask)
299
dma_2 = MaskedArray(dma_1)
300
assert_equal(dma_2.mask, dma_1.mask)
301
dma_3 = MaskedArray(dma_1, mask=[1, 0, 0, 0] * 6)
302
fail_if_equal(dma_3.mask, dma_1.mask)
303
304
x = array([1, 2, 3], mask=True)
305
assert_equal(x._mask, [True, True, True])
306
x = array([1, 2, 3], mask=False)
307
assert_equal(x._mask, [False, False, False])
308
y = array([1, 2, 3], mask=x._mask, copy=False)
309
assert_(np.may_share_memory(x.mask, y.mask))
310
y = array([1, 2, 3], mask=x._mask, copy=True)
311
assert_(not np.may_share_memory(x.mask, y.mask))
312
x = array([1, 2, 3], mask=None)
313
assert_equal(x._mask, [False, False, False])
314
315
def test_masked_singleton_array_creation_warns(self):
316
# The first works, but should not (ideally), there may be no way
317
# to solve this, however, as long as `np.ma.masked` is an ndarray.
318
np.array(np.ma.masked)
319
with pytest.warns(UserWarning):
320
# Tries to create a float array, using `float(np.ma.masked)`.
321
# We may want to define this is invalid behaviour in the future!
322
# (requiring np.ma.masked to be a known NumPy scalar probably
323
# with a DType.)
324
np.array([3., np.ma.masked])
325
326
def test_creation_with_list_of_maskedarrays(self):
327
# Tests creating a masked array from a list of masked arrays.
328
x = array(np.arange(5), mask=[1, 0, 0, 0, 0])
329
data = array((x, x[::-1]))
330
assert_equal(data, [[0, 1, 2, 3, 4], [4, 3, 2, 1, 0]])
331
assert_equal(data._mask, [[1, 0, 0, 0, 0], [0, 0, 0, 0, 1]])
332
333
x.mask = nomask
334
data = array((x, x[::-1]))
335
assert_equal(data, [[0, 1, 2, 3, 4], [4, 3, 2, 1, 0]])
336
assert_(data.mask is nomask)
337
338
def test_creation_with_list_of_maskedarrays_no_bool_cast(self):
339
# Tests the regression in gh-18551
340
masked_str = np.ma.masked_array(['a', 'b'], mask=[True, False])
341
normal_int = np.arange(2)
342
res = np.ma.asarray([masked_str, normal_int], dtype="U21")
343
assert_array_equal(res.mask, [[True, False], [False, False]])
344
345
# The above only failed due a long chain of oddity, try also with
346
# an object array that cannot be converted to bool always:
347
class NotBool:
348
def __bool__(self):
349
raise ValueError("not a bool!")
350
masked_obj = np.ma.masked_array([NotBool(), 'b'], mask=[True, False])
351
# Check that the NotBool actually fails like we would expect:
352
with pytest.raises(ValueError, match="not a bool!"):
353
np.asarray([masked_obj], dtype=bool)
354
355
res = np.ma.asarray([masked_obj, normal_int])
356
assert_array_equal(res.mask, [[True, False], [False, False]])
357
358
def test_creation_from_ndarray_with_padding(self):
359
x = np.array([('A', 0)], dtype={'names': ['f0', 'f1'],
360
'formats': ['S4', 'i8'],
361
'offsets': [0, 8]})
362
array(x) # used to fail due to 'V' padding field in x.dtype.descr
363
364
def test_unknown_keyword_parameter(self):
365
with pytest.raises(TypeError, match="unexpected keyword argument"):
366
MaskedArray([1, 2, 3], maks=[0, 1, 0]) # `mask` is misspelled.
367
368
def test_asarray(self):
369
xm = self._create_data()[5]
370
xm.fill_value = -9999
371
xm._hardmask = True
372
xmm = asarray(xm)
373
assert_equal(xmm._data, xm._data)
374
assert_equal(xmm._mask, xm._mask)
375
assert_equal(xmm.fill_value, xm.fill_value)
376
assert_equal(xmm._hardmask, xm._hardmask)
377
378
def test_asarray_default_order(self):
379
# See Issue #6646
380
m = np.eye(3).T
381
assert_(not m.flags.c_contiguous)
382
383
new_m = asarray(m)
384
assert_(new_m.flags.c_contiguous)
385
386
def test_asarray_enforce_order(self):
387
# See Issue #6646
388
m = np.eye(3).T
389
assert_(not m.flags.c_contiguous)
390
391
new_m = asarray(m, order='C')
392
assert_(new_m.flags.c_contiguous)
393
394
def test_fix_invalid(self):
395
# Checks fix_invalid.
396
with np.errstate(invalid='ignore'):
397
data = masked_array([np.nan, 0., 1.], mask=[0, 0, 1])
398
data_fixed = fix_invalid(data)
399
assert_equal(data_fixed._data, [data.fill_value, 0., 1.])
400
assert_equal(data_fixed._mask, [1., 0., 1.])
401
402
def test_maskedelement(self):
403
# Test of masked element
404
x = arange(6)
405
x[1] = masked
406
assert_(str(masked) == '--')
407
assert_(x[1] is masked)
408
assert_equal(filled(x[1], 0), 0)
409
410
def test_set_element_as_object(self):
411
# Tests setting elements with object
412
a = empty(1, dtype=object)
413
x = (1, 2, 3, 4, 5)
414
a[0] = x
415
assert_equal(a[0], x)
416
assert_(a[0] is x)
417
418
import datetime
419
dt = datetime.datetime.now()
420
a[0] = dt
421
assert_(a[0] is dt)
422
423
def test_indexing(self):
424
# Tests conversions and indexing
425
x1 = np.array([1, 2, 4, 3])
426
x2 = array(x1, mask=[1, 0, 0, 0])
427
x3 = array(x1, mask=[0, 1, 0, 1])
428
x4 = array(x1)
429
# test conversion to strings
430
str(x2) # raises?
431
repr(x2) # raises?
432
assert_equal(np.sort(x1), sort(x2, endwith=False))
433
# tests of indexing
434
assert_(type(x2[1]) is type(x1[1]))
435
assert_(x1[1] == x2[1])
436
assert_(x2[0] is masked)
437
assert_equal(x1[2], x2[2])
438
assert_equal(x1[2:5], x2[2:5])
439
assert_equal(x1[:], x2[:])
440
assert_equal(x1[1:], x3[1:])
441
x1[2] = 9
442
x2[2] = 9
443
assert_equal(x1, x2)
444
x1[1:3] = 99
445
x2[1:3] = 99
446
assert_equal(x1, x2)
447
x2[1] = masked
448
assert_equal(x1, x2)
449
x2[1:3] = masked
450
assert_equal(x1, x2)
451
x2[:] = x1
452
x2[1] = masked
453
assert_(allequal(getmask(x2), array([0, 1, 0, 0])))
454
x3[:] = masked_array([1, 2, 3, 4], [0, 1, 1, 0])
455
assert_(allequal(getmask(x3), array([0, 1, 1, 0])))
456
x4[:] = masked_array([1, 2, 3, 4], [0, 1, 1, 0])
457
assert_(allequal(getmask(x4), array([0, 1, 1, 0])))
458
assert_(allequal(x4, array([1, 2, 3, 4])))
459
x1 = np.arange(5) * 1.0
460
x2 = masked_values(x1, 3.0)
461
assert_equal(x1, x2)
462
assert_(allequal(array([0, 0, 0, 1, 0], MaskType), x2.mask))
463
assert_equal(3.0, x2.fill_value)
464
x1 = array([1, 'hello', 2, 3], object)
465
x2 = np.array([1, 'hello', 2, 3], object)
466
s1 = x1[1]
467
s2 = x2[1]
468
assert_equal(type(s2), str)
469
assert_equal(type(s1), str)
470
assert_equal(s1, s2)
471
assert_(x1[1:1].shape == (0,))
472
473
def test_setitem_no_warning(self):
474
# Setitem shouldn't warn, because the assignment might be masked
475
# and warning for a masked assignment is weird (see gh-23000)
476
# (When the value is masked, otherwise a warning would be acceptable
477
# but is not given currently.)
478
x = np.ma.arange(60).reshape((6, 10))
479
index = (slice(1, 5, 2), [7, 5])
480
value = np.ma.masked_all((2, 2))
481
value._data[...] = np.inf # not a valid integer...
482
x[index] = value
483
# The masked scalar is special cased, but test anyway (it's NaN):
484
x[...] = np.ma.masked
485
# Finally, a large value that cannot be cast to the float32 `x`
486
x = np.ma.arange(3., dtype=np.float32)
487
value = np.ma.array([2e234, 1, 1], mask=[True, False, False])
488
x[...] = value
489
x[[0, 1, 2]] = value
490
491
@pytest.mark.filterwarnings(WARNING_MARK_SPEC)
492
def test_copy(self):
493
# Tests of some subtle points of copying and sizing.
494
n = [0, 0, 1, 0, 0]
495
m = make_mask(n)
496
m2 = make_mask(m)
497
assert_(m is m2)
498
m3 = make_mask(m, copy=True)
499
assert_(m is not m3)
500
501
x1 = np.arange(5)
502
y1 = array(x1, mask=m)
503
assert_equal(y1._data.__array_interface__, x1.__array_interface__)
504
assert_(allequal(x1, y1.data))
505
assert_equal(y1._mask.__array_interface__, m.__array_interface__)
506
507
y1a = array(y1)
508
# Default for masked array is not to copy; see gh-10318.
509
assert_(y1a._data.__array_interface__ ==
510
y1._data.__array_interface__)
511
assert_(y1a._mask.__array_interface__ ==
512
y1._mask.__array_interface__)
513
514
y2 = array(x1, mask=m3)
515
assert_(y2._data.__array_interface__ == x1.__array_interface__)
516
assert_(y2._mask.__array_interface__ == m3.__array_interface__)
517
assert_(y2[2] is masked)
518
y2[2] = 9
519
assert_(y2[2] is not masked)
520
assert_(y2._mask.__array_interface__ == m3.__array_interface__)
521
assert_(allequal(y2.mask, 0))
522
523
y2a = array(x1, mask=m, copy=1)
524
assert_(y2a._data.__array_interface__ != x1.__array_interface__)
525
#assert_( y2a._mask is not m)
526
assert_(y2a._mask.__array_interface__ != m.__array_interface__)
527
assert_(y2a[2] is masked)
528
y2a[2] = 9
529
assert_(y2a[2] is not masked)
530
#assert_( y2a._mask is not m)
531
assert_(y2a._mask.__array_interface__ != m.__array_interface__)
532
assert_(allequal(y2a.mask, 0))
533
534
y3 = array(x1 * 1.0, mask=m)
535
assert_(filled(y3).dtype is (x1 * 1.0).dtype)
536
537
x4 = arange(4)
538
x4[2] = masked
539
y4 = resize(x4, (8,))
540
assert_equal(concatenate([x4, x4]), y4)
541
assert_equal(getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0])
542
y5 = repeat(x4, (2, 2, 2, 2), axis=0)
543
assert_equal(y5, [0, 0, 1, 1, 2, 2, 3, 3])
544
y6 = repeat(x4, 2, axis=0)
545
assert_equal(y5, y6)
546
y7 = x4.repeat((2, 2, 2, 2), axis=0)
547
assert_equal(y5, y7)
548
y8 = x4.repeat(2, 0)
549
assert_equal(y5, y8)
550
551
y9 = x4.copy()
552
assert_equal(y9._data, x4._data)
553
assert_equal(y9._mask, x4._mask)
554
555
x = masked_array([1, 2, 3], mask=[0, 1, 0])
556
# Copy is False by default
557
y = masked_array(x)
558
assert_equal(y._data.ctypes.data, x._data.ctypes.data)
559
assert_equal(y._mask.ctypes.data, x._mask.ctypes.data)
560
y = masked_array(x, copy=True)
561
assert_not_equal(y._data.ctypes.data, x._data.ctypes.data)
562
assert_not_equal(y._mask.ctypes.data, x._mask.ctypes.data)
563
564
def test_copy_0d(self):
565
# gh-9430
566
x = np.ma.array(43, mask=True)
567
xc = x.copy()
568
assert_equal(xc.mask, True)
569
570
def test_copy_on_python_builtins(self):
571
# Tests copy works on python builtins (issue#8019)
572
assert_(isMaskedArray(np.ma.copy([1, 2, 3])))
573
assert_(isMaskedArray(np.ma.copy((1, 2, 3))))
574
575
def test_copy_immutable(self):
576
# Tests that the copy method is immutable, GitHub issue #5247
577
a = np.ma.array([1, 2, 3])
578
b = np.ma.array([4, 5, 6])
579
a_copy_method = a.copy
580
b.copy
581
assert_equal(a_copy_method(), [1, 2, 3])
582
583
def test_deepcopy(self):
584
from copy import deepcopy
585
a = array([0, 1, 2], mask=[False, True, False])
586
copied = deepcopy(a)
587
assert_equal(copied.mask, a.mask)
588
assert_not_equal(id(a._mask), id(copied._mask))
589
590
copied[1] = 1
591
assert_equal(copied.mask, [0, 0, 0])
592
assert_equal(a.mask, [0, 1, 0])
593
594
copied = deepcopy(a)
595
assert_equal(copied.mask, a.mask)
596
copied.mask[1] = False
597
assert_equal(copied.mask, [0, 0, 0])
598
assert_equal(a.mask, [0, 1, 0])
599
600
def test_format(self):
601
a = array([0, 1, 2], mask=[False, True, False])
602
assert_equal(format(a), "[0 -- 2]")
603
assert_equal(format(masked), "--")
604
assert_equal(format(masked, ""), "--")
605
606
# Postponed from PR #15410, perhaps address in the future.
607
# assert_equal(format(masked, " >5"), " --")
608
# assert_equal(format(masked, " <5"), "-- ")
609
610
# Expect a FutureWarning for using format_spec with MaskedElement
611
with pytest.warns(FutureWarning):
612
with_format_string = format(masked, " >5")
613
assert_equal(with_format_string, "--")
614
615
def test_str_repr(self):
616
a = array([0, 1, 2], mask=[False, True, False])
617
assert_equal(str(a), '[0 -- 2]')
618
assert_equal(
619
repr(a),
620
textwrap.dedent('''\
621
masked_array(data=[0, --, 2],
622
mask=[False, True, False],
623
fill_value=999999)''')
624
)
625
626
# arrays with a continuation
627
a = np.ma.arange(2000)
628
a[1:50] = np.ma.masked
629
assert_equal(
630
repr(a),
631
textwrap.dedent('''\
632
masked_array(data=[0, --, --, ..., 1997, 1998, 1999],
633
mask=[False, True, True, ..., False, False, False],
634
fill_value=999999)''')
635
)
636
637
# line-wrapped 1d arrays are correctly aligned
638
a = np.ma.arange(20)
639
assert_equal(
640
repr(a),
641
textwrap.dedent('''\
642
masked_array(data=[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
643
14, 15, 16, 17, 18, 19],
644
mask=False,
645
fill_value=999999)''')
646
)
647
648
# 2d arrays cause wrapping
649
a = array([[1, 2, 3], [4, 5, 6]], dtype=np.int8)
650
a[1, 1] = np.ma.masked
651
assert_equal(
652
repr(a),
653
textwrap.dedent(f'''\
654
masked_array(
655
data=[[1, 2, 3],
656
[4, --, 6]],
657
mask=[[False, False, False],
658
[False, True, False]],
659
fill_value={np.array(999999)[()]!r},
660
dtype=int8)''')
661
)
662
663
# but not it they're a row vector
664
assert_equal(
665
repr(a[:1]),
666
textwrap.dedent(f'''\
667
masked_array(data=[[1, 2, 3]],
668
mask=[[False, False, False]],
669
fill_value={np.array(999999)[()]!r},
670
dtype=int8)''')
671
)
672
673
# dtype=int is implied, so not shown
674
assert_equal(
675
repr(a.astype(int)),
676
textwrap.dedent('''\
677
masked_array(
678
data=[[1, 2, 3],
679
[4, --, 6]],
680
mask=[[False, False, False],
681
[False, True, False]],
682
fill_value=999999)''')
683
)
684
685
def test_str_repr_legacy(self):
686
oldopts = np.get_printoptions()
687
np.set_printoptions(legacy='1.13')
688
try:
689
a = array([0, 1, 2], mask=[False, True, False])
690
assert_equal(str(a), '[0 -- 2]')
691
assert_equal(repr(a), 'masked_array(data = [0 -- 2],\n'
692
' mask = [False True False],\n'
693
' fill_value = 999999)\n')
694
695
a = np.ma.arange(2000)
696
a[1:50] = np.ma.masked
697
assert_equal(
698
repr(a),
699
'masked_array(data = [0 -- -- ..., 1997 1998 1999],\n'
700
' mask = [False True True ..., False False False],\n'
701
' fill_value = 999999)\n'
702
)
703
finally:
704
np.set_printoptions(**oldopts)
705
706
def test_0d_unicode(self):
707
u = 'caf\xe9'
708
utype = type(u)
709
710
arr_nomask = np.ma.array(u)
711
arr_masked = np.ma.array(u, mask=True)
712
713
assert_equal(utype(arr_nomask), u)
714
assert_equal(utype(arr_masked), '--')
715
716
def test_pickling(self):
717
# Tests pickling
718
for dtype in (int, float, str, object):
719
a = arange(10).astype(dtype)
720
a.fill_value = 999
721
722
masks = ([0, 0, 0, 1, 0, 1, 0, 1, 0, 1], # partially masked
723
True, # Fully masked
724
False) # Fully unmasked
725
726
for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
727
for mask in masks:
728
a.mask = mask
729
a_pickled = pickle.loads(pickle.dumps(a, protocol=proto))
730
assert_equal(a_pickled._mask, a._mask)
731
assert_equal(a_pickled._data, a._data)
732
if dtype in (object, int):
733
assert_equal(a_pickled.fill_value, 999)
734
else:
735
assert_equal(a_pickled.fill_value, dtype(999))
736
assert_array_equal(a_pickled.mask, mask)
737
738
def test_pickling_subbaseclass(self):
739
# Test pickling w/ a subclass of ndarray
740
x = np.array([(1.0, 2), (3.0, 4)],
741
dtype=[('x', float), ('y', int)]).view(np.recarray)
742
a = masked_array(x, mask=[(True, False), (False, True)])
743
for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
744
a_pickled = pickle.loads(pickle.dumps(a, protocol=proto))
745
assert_equal(a_pickled._mask, a._mask)
746
assert_equal(a_pickled, a)
747
assert_(isinstance(a_pickled._data, np.recarray))
748
749
def test_pickling_maskedconstant(self):
750
# Test pickling MaskedConstant
751
mc = np.ma.masked
752
for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
753
mc_pickled = pickle.loads(pickle.dumps(mc, protocol=proto))
754
assert_equal(mc_pickled._baseclass, mc._baseclass)
755
assert_equal(mc_pickled._mask, mc._mask)
756
assert_equal(mc_pickled._data, mc._data)
757
758
def test_pickling_wstructured(self):
759
# Tests pickling w/ structured array
760
a = array([(1, 1.), (2, 2.)], mask=[(0, 0), (0, 1)],
761
dtype=[('a', int), ('b', float)])
762
for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
763
a_pickled = pickle.loads(pickle.dumps(a, protocol=proto))
764
assert_equal(a_pickled._mask, a._mask)
765
assert_equal(a_pickled, a)
766
767
def test_pickling_keepalignment(self):
768
# Tests pickling w/ F_CONTIGUOUS arrays
769
a = arange(10).reshape( (-1, 2))
770
b = a.T
771
for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
772
test = pickle.loads(pickle.dumps(b, protocol=proto))
773
assert_equal(test, b)
774
775
def test_single_element_subscript(self):
776
# Tests single element subscripts of Maskedarrays.
777
a = array([1, 3, 2])
778
b = array([1, 3, 2], mask=[1, 0, 1])
779
assert_equal(a[0].shape, ())
780
assert_equal(b[0].shape, ())
781
assert_equal(b[1].shape, ())
782
783
def test_topython(self):
784
# Tests some communication issues with Python.
785
assert_equal(1, int(array(1)))
786
assert_equal(1.0, float(array(1)))
787
assert_equal(1, int(array([[[1]]])))
788
assert_equal(1.0, float(array([[1]])))
789
assert_raises(TypeError, float, array([1, 1]))
790
791
with warnings.catch_warnings():
792
warnings.filterwarnings(
793
'ignore', 'Warning: converting a masked element', UserWarning)
794
assert_(np.isnan(float(array([1], mask=[1]))))
795
796
a = array([1, 2, 3], mask=[1, 0, 0])
797
assert_raises(TypeError, lambda: float(a))
798
assert_equal(float(a[-1]), 3.)
799
assert_(np.isnan(float(a[0])))
800
assert_raises(TypeError, int, a)
801
assert_equal(int(a[-1]), 3)
802
assert_raises(MAError, lambda: int(a[0]))
803
804
def test_oddfeatures_1(self):
805
# Test of other odd features
806
x = arange(20)
807
x = x.reshape(4, 5)
808
x.flat[5] = 12
809
assert_(x[1, 0] == 12)
810
z = x + 10j * x
811
assert_equal(z.real, x)
812
assert_equal(z.imag, 10 * x)
813
assert_equal((z * conjugate(z)).real, 101 * x * x)
814
z.imag[...] = 0.0
815
816
x = arange(10)
817
x[3] = masked
818
assert_(str(x[3]) == str(masked))
819
c = x >= 8
820
assert_(count(where(c, masked, masked)) == 0)
821
assert_(shape(where(c, masked, masked)) == c.shape)
822
823
z = masked_where(c, x)
824
assert_(z.dtype is x.dtype)
825
assert_(z[3] is masked)
826
assert_(z[4] is not masked)
827
assert_(z[7] is not masked)
828
assert_(z[8] is masked)
829
assert_(z[9] is masked)
830
assert_equal(x, z)
831
832
def test_oddfeatures_2(self):
833
# Tests some more features.
834
x = array([1., 2., 3., 4., 5.])
835
c = array([1, 1, 1, 0, 0])
836
x[2] = masked
837
z = where(c, x, -x)
838
assert_equal(z, [1., 2., 0., -4., -5])
839
c[0] = masked
840
z = where(c, x, -x)
841
assert_equal(z, [1., 2., 0., -4., -5])
842
assert_(z[0] is masked)
843
assert_(z[1] is not masked)
844
assert_(z[2] is masked)
845
846
def test_oddfeatures_3(self):
847
msg = "setting an item on a masked array which has a shared mask will not copy"
848
with warnings.catch_warnings():
849
warnings.filterwarnings(
850
'ignore', msg, numpy.ma.core.MaskedArrayFutureWarning)
851
# Tests some generic features
852
atest = array([10], mask=True)
853
btest = array([20])
854
idx = atest.mask
855
atest[idx] = btest[idx]
856
assert_equal(atest, [20])
857
858
def test_filled_with_object_dtype(self):
859
a = np.ma.masked_all(1, dtype='O')
860
assert_equal(a.filled('x')[0], 'x')
861
862
def test_filled_with_flexible_dtype(self):
863
# Test filled w/ flexible dtype
864
flexi = array([(1, 1, 1)],
865
dtype=[('i', int), ('s', '|S8'), ('f', float)])
866
flexi[0] = masked
867
assert_equal(flexi.filled(),
868
np.array([(default_fill_value(0),
869
default_fill_value('0'),
870
default_fill_value(0.),)], dtype=flexi.dtype))
871
flexi[0] = masked
872
assert_equal(flexi.filled(1),
873
np.array([(1, '1', 1.)], dtype=flexi.dtype))
874
875
def test_filled_with_mvoid(self):
876
# Test filled w/ mvoid
877
ndtype = [('a', int), ('b', float)]
878
a = mvoid((1, 2.), mask=[(0, 1)], dtype=ndtype)
879
# Filled using default
880
test = a.filled()
881
assert_equal(tuple(test), (1, default_fill_value(1.)))
882
# Explicit fill_value
883
test = a.filled((-1, -1))
884
assert_equal(tuple(test), (1, -1))
885
# Using predefined filling values
886
a.fill_value = (-999, -999)
887
assert_equal(tuple(a.filled()), (1, -999))
888
889
def test_filled_with_nested_dtype(self):
890
# Test filled w/ nested dtype
891
ndtype = [('A', int), ('B', [('BA', int), ('BB', int)])]
892
a = array([(1, (1, 1)), (2, (2, 2))],
893
mask=[(0, (1, 0)), (0, (0, 1))], dtype=ndtype)
894
test = a.filled(0)
895
control = np.array([(1, (0, 1)), (2, (2, 0))], dtype=ndtype)
896
assert_equal(test, control)
897
898
test = a['B'].filled(0)
899
control = np.array([(0, 1), (2, 0)], dtype=a['B'].dtype)
900
assert_equal(test, control)
901
902
# test if mask gets set correctly (see #6760)
903
Z = numpy.ma.zeros(2, numpy.dtype([("A", "(2,2)i1,(2,2)i1", (2, 2))]))
904
assert_equal(Z.data.dtype, numpy.dtype([('A', [('f0', 'i1', (2, 2)),
905
('f1', 'i1', (2, 2))], (2, 2))]))
906
assert_equal(Z.mask.dtype, numpy.dtype([('A', [('f0', '?', (2, 2)),
907
('f1', '?', (2, 2))], (2, 2))]))
908
909
def test_filled_with_f_order(self):
910
# Test filled w/ F-contiguous array
911
a = array(np.array([(0, 1, 2), (4, 5, 6)], order='F'),
912
mask=np.array([(0, 0, 1), (1, 0, 0)], order='F'),
913
order='F') # this is currently ignored
914
assert_(a.flags['F_CONTIGUOUS'])
915
assert_(a.filled(0).flags['F_CONTIGUOUS'])
916
917
def test_optinfo_propagation(self):
918
# Checks that _optinfo dictionary isn't back-propagated
919
x = array([1, 2, 3, ], dtype=float)
920
x._optinfo['info'] = '???'
921
y = x.copy()
922
assert_equal(y._optinfo['info'], '???')
923
y._optinfo['info'] = '!!!'
924
assert_equal(x._optinfo['info'], '???')
925
926
def test_optinfo_forward_propagation(self):
927
a = array([1, 2, 2, 4])
928
a._optinfo["key"] = "value"
929
assert_equal(a._optinfo["key"], (a == 2)._optinfo["key"])
930
assert_equal(a._optinfo["key"], (a != 2)._optinfo["key"])
931
assert_equal(a._optinfo["key"], (a > 2)._optinfo["key"])
932
assert_equal(a._optinfo["key"], (a >= 2)._optinfo["key"])
933
assert_equal(a._optinfo["key"], (a <= 2)._optinfo["key"])
934
assert_equal(a._optinfo["key"], (a + 2)._optinfo["key"])
935
assert_equal(a._optinfo["key"], (a - 2)._optinfo["key"])
936
assert_equal(a._optinfo["key"], (a * 2)._optinfo["key"])
937
assert_equal(a._optinfo["key"], (a / 2)._optinfo["key"])
938
assert_equal(a._optinfo["key"], a[:2]._optinfo["key"])
939
assert_equal(a._optinfo["key"], a[[0, 0, 2]]._optinfo["key"])
940
assert_equal(a._optinfo["key"], np.exp(a)._optinfo["key"])
941
assert_equal(a._optinfo["key"], np.abs(a)._optinfo["key"])
942
assert_equal(a._optinfo["key"], array(a, copy=True)._optinfo["key"])
943
assert_equal(a._optinfo["key"], np.zeros_like(a)._optinfo["key"])
944
945
def test_fancy_printoptions(self):
946
# Test printing a masked array w/ fancy dtype.
947
fancydtype = np.dtype([('x', int), ('y', [('t', int), ('s', float)])])
948
test = array([(1, (2, 3.0)), (4, (5, 6.0))],
949
mask=[(1, (0, 1)), (0, (1, 0))],
950
dtype=fancydtype)
951
control = "[(--, (2, --)) (4, (--, 6.0))]"
952
assert_equal(str(test), control)
953
954
# Test 0-d array with multi-dimensional dtype
955
t_2d0 = masked_array(data=(0, [[0.0, 0.0, 0.0],
956
[0.0, 0.0, 0.0]],
957
0.0),
958
mask=(False, [[True, False, True],
959
[False, False, True]],
960
False),
961
dtype="int, (2,3)float, float")
962
control = "(0, [[--, 0.0, --], [0.0, 0.0, --]], 0.0)"
963
assert_equal(str(t_2d0), control)
964
965
def test_flatten_structured_array(self):
966
# Test flatten_structured_array on arrays
967
# On ndarray
968
ndtype = [('a', int), ('b', float)]
969
a = np.array([(1, 1), (2, 2)], dtype=ndtype)
970
test = flatten_structured_array(a)
971
control = np.array([[1., 1.], [2., 2.]], dtype=float)
972
assert_equal(test, control)
973
assert_equal(test.dtype, control.dtype)
974
# On masked_array
975
a = array([(1, 1), (2, 2)], mask=[(0, 1), (1, 0)], dtype=ndtype)
976
test = flatten_structured_array(a)
977
control = array([[1., 1.], [2., 2.]],
978
mask=[[0, 1], [1, 0]], dtype=float)
979
assert_equal(test, control)
980
assert_equal(test.dtype, control.dtype)
981
assert_equal(test.mask, control.mask)
982
# On masked array with nested structure
983
ndtype = [('a', int), ('b', [('ba', int), ('bb', float)])]
984
a = array([(1, (1, 1.1)), (2, (2, 2.2))],
985
mask=[(0, (1, 0)), (1, (0, 1))], dtype=ndtype)
986
test = flatten_structured_array(a)
987
control = array([[1., 1., 1.1], [2., 2., 2.2]],
988
mask=[[0, 1, 0], [1, 0, 1]], dtype=float)
989
assert_equal(test, control)
990
assert_equal(test.dtype, control.dtype)
991
assert_equal(test.mask, control.mask)
992
# Keeping the initial shape
993
ndtype = [('a', int), ('b', float)]
994
a = np.array([[(1, 1), ], [(2, 2), ]], dtype=ndtype)
995
test = flatten_structured_array(a)
996
control = np.array([[[1., 1.], ], [[2., 2.], ]], dtype=float)
997
assert_equal(test, control)
998
assert_equal(test.dtype, control.dtype)
999
1000
def test_void0d(self):
1001
# Test creating a mvoid object
1002
ndtype = [('a', int), ('b', int)]
1003
a = np.array([(1, 2,)], dtype=ndtype)[0]
1004
f = mvoid(a)
1005
assert_(isinstance(f, mvoid))
1006
1007
a = masked_array([(1, 2)], mask=[(1, 0)], dtype=ndtype)[0]
1008
assert_(isinstance(a, mvoid))
1009
1010
a = masked_array([(1, 2), (1, 2)], mask=[(1, 0), (0, 0)], dtype=ndtype)
1011
f = mvoid(a._data[0], a._mask[0])
1012
assert_(isinstance(f, mvoid))
1013
1014
def test_mvoid_getitem(self):
1015
# Test mvoid.__getitem__
1016
ndtype = [('a', int), ('b', int)]
1017
a = masked_array([(1, 2,), (3, 4)], mask=[(0, 0), (1, 0)],
1018
dtype=ndtype)
1019
# w/o mask
1020
f = a[0]
1021
assert_(isinstance(f, mvoid))
1022
assert_equal((f[0], f['a']), (1, 1))
1023
assert_equal(f['b'], 2)
1024
# w/ mask
1025
f = a[1]
1026
assert_(isinstance(f, mvoid))
1027
assert_(f[0] is masked)
1028
assert_(f['a'] is masked)
1029
assert_equal(f[1], 4)
1030
1031
# exotic dtype
1032
A = masked_array(data=[([0, 1],)],
1033
mask=[([True, False],)],
1034
dtype=[("A", ">i2", (2,))])
1035
assert_equal(A[0]["A"], A["A"][0])
1036
assert_equal(A[0]["A"], masked_array(data=[0, 1],
1037
mask=[True, False], dtype=">i2"))
1038
1039
def test_mvoid_iter(self):
1040
# Test iteration on __getitem__
1041
ndtype = [('a', int), ('b', int)]
1042
a = masked_array([(1, 2,), (3, 4)], mask=[(0, 0), (1, 0)],
1043
dtype=ndtype)
1044
# w/o mask
1045
assert_equal(list(a[0]), [1, 2])
1046
# w/ mask
1047
assert_equal(list(a[1]), [masked, 4])
1048
1049
@pytest.mark.thread_unsafe(reason="masked_print_option.set_display global state")
1050
def test_mvoid_print(self):
1051
# Test printing a mvoid
1052
mx = array([(1, 1), (2, 2)], dtype=[('a', int), ('b', int)])
1053
assert_equal(str(mx[0]), "(1, 1)")
1054
mx['b'][0] = masked
1055
ini_display = masked_print_option._display
1056
masked_print_option.set_display("-X-")
1057
try:
1058
assert_equal(str(mx[0]), "(1, -X-)")
1059
assert_equal(repr(mx[0]), "(1, -X-)")
1060
finally:
1061
masked_print_option.set_display(ini_display)
1062
1063
# also check if there are object datatypes (see gh-7493)
1064
mx = array([(1,), (2,)], dtype=[('a', 'O')])
1065
assert_equal(str(mx[0]), "(1,)")
1066
1067
@pytest.mark.thread_unsafe(reason="masked_print_option global state")
1068
def test_mvoid_multidim_print(self):
1069
1070
# regression test for gh-6019
1071
t_ma = masked_array(data=[([1, 2, 3],)],
1072
mask=[([False, True, False],)],
1073
fill_value=([999999, 999999, 999999],),
1074
dtype=[('a', '<i4', (3,))])
1075
assert_(str(t_ma[0]) == "([1, --, 3],)")
1076
assert_(repr(t_ma[0]) == "([1, --, 3],)")
1077
1078
# additional tests with structured arrays
1079
1080
t_2d = masked_array(data=[([[1, 2], [3, 4]],)],
1081
mask=[([[False, True], [True, False]],)],
1082
dtype=[('a', '<i4', (2, 2))])
1083
assert_(str(t_2d[0]) == "([[1, --], [--, 4]],)")
1084
assert_(repr(t_2d[0]) == "([[1, --], [--, 4]],)")
1085
1086
t_0d = masked_array(data=[(1, 2)],
1087
mask=[(True, False)],
1088
dtype=[('a', '<i4'), ('b', '<i4')])
1089
assert_(str(t_0d[0]) == "(--, 2)")
1090
assert_(repr(t_0d[0]) == "(--, 2)")
1091
1092
t_2d = masked_array(data=[([[1, 2], [3, 4]], 1)],
1093
mask=[([[False, True], [True, False]], False)],
1094
dtype=[('a', '<i4', (2, 2)), ('b', float)])
1095
assert_(str(t_2d[0]) == "([[1, --], [--, 4]], 1.0)")
1096
assert_(repr(t_2d[0]) == "([[1, --], [--, 4]], 1.0)")
1097
1098
t_ne = masked_array(data=[(1, (1, 1))],
1099
mask=[(True, (True, False))],
1100
dtype=[('a', '<i4'), ('b', 'i4,i4')])
1101
assert_(str(t_ne[0]) == "(--, (--, 1))")
1102
assert_(repr(t_ne[0]) == "(--, (--, 1))")
1103
1104
def test_object_with_array(self):
1105
mx1 = masked_array([1.], mask=[True])
1106
mx2 = masked_array([1., 2.])
1107
mx = masked_array([mx1, mx2], mask=[False, True], dtype=object)
1108
assert_(mx[0] is mx1)
1109
assert_(mx[1] is not mx2)
1110
assert_(np.all(mx[1].data == mx2.data))
1111
assert_(np.all(mx[1].mask))
1112
# check that we return a view.
1113
mx[1].data[0] = 0.
1114
assert_(mx2[0] == 0.)
1115
1116
def test_maskedarray_tofile_raises_notimplementederror(self):
1117
xm = masked_array([1, 2, 3], mask=[False, True, False])
1118
# Test case to check the NotImplementedError.
1119
# It is not implemented at this point of time. We can change this in future
1120
with temppath(suffix='.npy') as path:
1121
with pytest.raises(NotImplementedError):
1122
np.save(path, xm)
1123
1124
1125
class TestMaskedArrayArithmetic:
1126
# Base test class for MaskedArrays.
1127
def _create_data(self):
1128
# Base data definition.
1129
x = np.array([1., 1., 1., -2., pi / 2.0, 4., 5., -10., 10., 1., 2., 3.])
1130
y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
1131
a10 = 10.
1132
m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
1133
m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
1134
xm = masked_array(x, mask=m1)
1135
ym = masked_array(y, mask=m2)
1136
z = np.array([-.5, 0., .5, .8])
1137
zm = masked_array(z, mask=[0, 1, 0, 0])
1138
xf = np.where(m1, 1e+20, x)
1139
xm.set_fill_value(1e+20)
1140
return x, y, a10, m1, m2, xm, ym, z, zm, xf
1141
1142
@pytest.fixture(autouse=True, scope="class")
1143
def err_status(self):
1144
err = np.geterr()
1145
np.seterr(divide='ignore', invalid='ignore')
1146
yield err
1147
np.seterr(**err)
1148
1149
def test_basic_arithmetic(self):
1150
# Test of basic arithmetic.
1151
x, y, a10, _, _, xm, ym, _, _, xf = self._create_data()
1152
a2d = array([[1, 2], [0, 4]])
1153
a2dm = masked_array(a2d, [[0, 0], [1, 0]])
1154
assert_equal(a2d * a2d, a2d * a2dm)
1155
assert_equal(a2d + a2d, a2d + a2dm)
1156
assert_equal(a2d - a2d, a2d - a2dm)
1157
for s in [(12,), (4, 3), (2, 6)]:
1158
x = x.reshape(s)
1159
y = y.reshape(s)
1160
xm = xm.reshape(s)
1161
ym = ym.reshape(s)
1162
xf = xf.reshape(s)
1163
assert_equal(-x, -xm)
1164
assert_equal(x + y, xm + ym)
1165
assert_equal(x - y, xm - ym)
1166
assert_equal(x * y, xm * ym)
1167
assert_equal(x / y, xm / ym)
1168
assert_equal(a10 + y, a10 + ym)
1169
assert_equal(a10 - y, a10 - ym)
1170
assert_equal(a10 * y, a10 * ym)
1171
assert_equal(a10 / y, a10 / ym)
1172
assert_equal(x + a10, xm + a10)
1173
assert_equal(x - a10, xm - a10)
1174
assert_equal(x * a10, xm * a10)
1175
assert_equal(x / a10, xm / a10)
1176
assert_equal(x ** 2, xm ** 2)
1177
assert_equal(abs(x) ** 2.5, abs(xm) ** 2.5)
1178
assert_equal(x ** y, xm ** ym)
1179
assert_equal(np.add(x, y), add(xm, ym))
1180
assert_equal(np.subtract(x, y), subtract(xm, ym))
1181
assert_equal(np.multiply(x, y), multiply(xm, ym))
1182
assert_equal(np.divide(x, y), divide(xm, ym))
1183
1184
def test_divide_on_different_shapes(self):
1185
x = arange(6, dtype=float).reshape((2, 3))
1186
y = arange(3, dtype=float)
1187
1188
z = x / y
1189
assert_equal(z, [[-1., 1., 1.], [-1., 4., 2.5]])
1190
assert_equal(z.mask, [[1, 0, 0], [1, 0, 0]])
1191
1192
z = x / y[None, :]
1193
assert_equal(z, [[-1., 1., 1.], [-1., 4., 2.5]])
1194
assert_equal(z.mask, [[1, 0, 0], [1, 0, 0]])
1195
1196
y = arange(2, dtype=float)
1197
z = x / y[:, None]
1198
assert_equal(z, [[-1., -1., -1.], [3., 4., 5.]])
1199
assert_equal(z.mask, [[1, 1, 1], [0, 0, 0]])
1200
1201
def test_mixed_arithmetic(self):
1202
# Tests mixed arithmetic.
1203
na = np.array([1])
1204
ma = array([1])
1205
assert_(isinstance(na + ma, MaskedArray))
1206
assert_(isinstance(ma + na, MaskedArray))
1207
1208
def test_limits_arithmetic(self):
1209
tiny = np.finfo(float).tiny
1210
a = array([tiny, 1. / tiny, 0.])
1211
assert_equal(getmaskarray(a / 2), [0, 0, 0])
1212
assert_equal(getmaskarray(2 / a), [1, 0, 1])
1213
1214
def test_masked_singleton_arithmetic(self):
1215
# Tests some scalar arithmetic on MaskedArrays.
1216
# Masked singleton should remain masked no matter what
1217
xm = array(0, mask=1)
1218
assert_((1 / array(0)).mask)
1219
assert_((1 + xm).mask)
1220
assert_((-xm).mask)
1221
assert_(maximum(xm, xm).mask)
1222
assert_(minimum(xm, xm).mask)
1223
1224
def test_masked_singleton_equality(self):
1225
# Tests (in)equality on masked singleton
1226
a = array([1, 2, 3], mask=[1, 1, 0])
1227
assert_((a[0] == 0) is masked)
1228
assert_((a[0] != 0) is masked)
1229
assert_equal((a[-1] == 0), False)
1230
assert_equal((a[-1] != 0), True)
1231
1232
def test_arithmetic_with_masked_singleton(self):
1233
# Checks that there's no collapsing to masked
1234
x = masked_array([1, 2])
1235
y = x * masked
1236
assert_equal(y.shape, x.shape)
1237
assert_equal(y._mask, [True, True])
1238
y = x[0] * masked
1239
assert_(y is masked)
1240
y = x + masked
1241
assert_equal(y.shape, x.shape)
1242
assert_equal(y._mask, [True, True])
1243
1244
def test_arithmetic_with_masked_singleton_on_1d_singleton(self):
1245
# Check that we're not losing the shape of a singleton
1246
x = masked_array([1, ])
1247
y = x + masked
1248
assert_equal(y.shape, x.shape)
1249
assert_equal(y.mask, [True, ])
1250
1251
def test_scalar_arithmetic(self):
1252
x = array(0, mask=0)
1253
assert_equal(x.filled().ctypes.data, x.ctypes.data)
1254
# Make sure we don't lose the shape in some circumstances
1255
xm = array((0, 0)) / 0.
1256
assert_equal(xm.shape, (2,))
1257
assert_equal(xm.mask, [1, 1])
1258
1259
def test_basic_ufuncs(self):
1260
# Test various functions such as sin, cos.
1261
x, y, _, _, _, xm, ym, z, zm, _ = self._create_data()
1262
assert_equal(np.cos(x), cos(xm))
1263
assert_equal(np.cosh(x), cosh(xm))
1264
assert_equal(np.sin(x), sin(xm))
1265
assert_equal(np.sinh(x), sinh(xm))
1266
assert_equal(np.tan(x), tan(xm))
1267
assert_equal(np.tanh(x), tanh(xm))
1268
assert_equal(np.sqrt(abs(x)), sqrt(xm))
1269
assert_equal(np.log(abs(x)), log(xm))
1270
assert_equal(np.log10(abs(x)), log10(xm))
1271
assert_equal(np.exp(x), exp(xm))
1272
assert_equal(np.arcsin(z), arcsin(zm))
1273
assert_equal(np.arccos(z), arccos(zm))
1274
assert_equal(np.arctan(z), arctan(zm))
1275
assert_equal(np.arctan2(x, y), arctan2(xm, ym))
1276
assert_equal(np.absolute(x), absolute(xm))
1277
assert_equal(np.angle(x + 1j * y), angle(xm + 1j * ym))
1278
assert_equal(np.angle(x + 1j * y, deg=True), angle(xm + 1j * ym, deg=True))
1279
assert_equal(np.equal(x, y), equal(xm, ym))
1280
assert_equal(np.not_equal(x, y), not_equal(xm, ym))
1281
assert_equal(np.less(x, y), less(xm, ym))
1282
assert_equal(np.greater(x, y), greater(xm, ym))
1283
assert_equal(np.less_equal(x, y), less_equal(xm, ym))
1284
assert_equal(np.greater_equal(x, y), greater_equal(xm, ym))
1285
assert_equal(np.conjugate(x), conjugate(xm))
1286
1287
def test_basic_ufuncs_masked(self):
1288
# Mostly regression test for gh-25635
1289
assert np.sqrt(np.ma.masked) is np.ma.masked
1290
1291
def test_count_func(self):
1292
# Tests count
1293
assert_equal(1, count(1))
1294
assert_equal(0, array(1, mask=[1]))
1295
1296
ott = array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
1297
res = count(ott)
1298
assert_(res.dtype.type is np.intp)
1299
assert_equal(3, res)
1300
1301
ott = ott.reshape((2, 2))
1302
res = count(ott)
1303
assert_(res.dtype.type is np.intp)
1304
assert_equal(3, res)
1305
res = count(ott, 0)
1306
assert_(isinstance(res, ndarray))
1307
assert_equal([1, 2], res)
1308
assert_(getmask(res) is nomask)
1309
1310
ott = array([0., 1., 2., 3.])
1311
res = count(ott, 0)
1312
assert_(isinstance(res, ndarray))
1313
assert_(res.dtype.type is np.intp)
1314
assert_raises(AxisError, ott.count, axis=1)
1315
1316
def test_count_on_python_builtins(self):
1317
# Tests count works on python builtins (issue#8019)
1318
assert_equal(3, count([1, 2, 3]))
1319
assert_equal(2, count((1, 2)))
1320
1321
def test_minmax_func(self):
1322
# Tests minimum and maximum.
1323
x, y, _, _, _, xm, _, _, _, _ = self._create_data()
1324
# max doesn't work if shaped
1325
xr = np.ravel(x)
1326
xmr = ravel(xm)
1327
# following are true because of careful selection of data
1328
assert_equal(max(xr), maximum.reduce(xmr))
1329
assert_equal(min(xr), minimum.reduce(xmr))
1330
1331
assert_equal(minimum([1, 2, 3], [4, 0, 9]), [1, 0, 3])
1332
assert_equal(maximum([1, 2, 3], [4, 0, 9]), [4, 2, 9])
1333
x = arange(5)
1334
y = arange(5) - 2
1335
x[3] = masked
1336
y[0] = masked
1337
assert_equal(minimum(x, y), where(less(x, y), x, y))
1338
assert_equal(maximum(x, y), where(greater(x, y), x, y))
1339
assert_(minimum.reduce(x) == 0)
1340
assert_(maximum.reduce(x) == 4)
1341
1342
x = arange(4).reshape(2, 2)
1343
x[-1, -1] = masked
1344
assert_equal(maximum.reduce(x, axis=None), 2)
1345
1346
def test_minimummaximum_func(self):
1347
a = np.ones((2, 2))
1348
aminimum = minimum(a, a)
1349
assert_(isinstance(aminimum, MaskedArray))
1350
assert_equal(aminimum, np.minimum(a, a))
1351
1352
aminimum = minimum.outer(a, a)
1353
assert_(isinstance(aminimum, MaskedArray))
1354
assert_equal(aminimum, np.minimum.outer(a, a))
1355
1356
amaximum = maximum(a, a)
1357
assert_(isinstance(amaximum, MaskedArray))
1358
assert_equal(amaximum, np.maximum(a, a))
1359
1360
amaximum = maximum.outer(a, a)
1361
assert_(isinstance(amaximum, MaskedArray))
1362
assert_equal(amaximum, np.maximum.outer(a, a))
1363
1364
def test_minmax_reduce(self):
1365
# Test np.min/maximum.reduce on array w/ full False mask
1366
a = array([1, 2, 3], mask=[False, False, False])
1367
b = np.maximum.reduce(a)
1368
assert_equal(b, 3)
1369
1370
def test_minmax_funcs_with_output(self):
1371
# Tests the min/max functions with explicit outputs
1372
mask = np.random.rand(12).round()
1373
xm = array(np.random.uniform(0, 10, 12), mask=mask)
1374
xm.shape = (3, 4)
1375
for funcname in ('min', 'max'):
1376
# Initialize
1377
npfunc = getattr(np, funcname)
1378
mafunc = getattr(numpy.ma.core, funcname)
1379
# Use the np version
1380
nout = np.empty((4,), dtype=int)
1381
try:
1382
result = npfunc(xm, axis=0, out=nout)
1383
except MaskError:
1384
pass
1385
nout = np.empty((4,), dtype=float)
1386
result = npfunc(xm, axis=0, out=nout)
1387
assert_(result is nout)
1388
# Use the ma version
1389
nout.fill(-999)
1390
result = mafunc(xm, axis=0, out=nout)
1391
assert_(result is nout)
1392
1393
def test_minmax_methods(self):
1394
# Additional tests on max/min
1395
xm = self._create_data()[5]
1396
xm.shape = (xm.size,)
1397
assert_equal(xm.max(), 10)
1398
assert_(xm[0].max() is masked)
1399
assert_(xm[0].max(0) is masked)
1400
assert_(xm[0].max(-1) is masked)
1401
assert_equal(xm.min(), -10.)
1402
assert_(xm[0].min() is masked)
1403
assert_(xm[0].min(0) is masked)
1404
assert_(xm[0].min(-1) is masked)
1405
assert_equal(xm.ptp(), 20.)
1406
assert_(xm[0].ptp() is masked)
1407
assert_(xm[0].ptp(0) is masked)
1408
assert_(xm[0].ptp(-1) is masked)
1409
1410
x = array([1, 2, 3], mask=True)
1411
assert_(x.min() is masked)
1412
assert_(x.max() is masked)
1413
assert_(x.ptp() is masked)
1414
1415
def test_minmax_dtypes(self):
1416
# Additional tests on max/min for non-standard float and complex dtypes
1417
x = np.array([1., 1., 1., -2., pi / 2.0, 4., 5., -10., 10., 1., 2., 3.])
1418
a10 = 10.
1419
an10 = -10.0
1420
m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
1421
xm = masked_array(x, mask=m1)
1422
xm.set_fill_value(1e+20)
1423
float_dtypes = [np.float16, np.float32, np.float64, np.longdouble,
1424
np.complex64, np.complex128, np.clongdouble]
1425
for float_dtype in float_dtypes:
1426
assert_equal(masked_array(x, mask=m1, dtype=float_dtype).max(),
1427
float_dtype(a10))
1428
assert_equal(masked_array(x, mask=m1, dtype=float_dtype).min(),
1429
float_dtype(an10))
1430
1431
assert_equal(xm.min(), an10)
1432
assert_equal(xm.max(), a10)
1433
1434
# Non-complex type only test
1435
for float_dtype in float_dtypes[:4]:
1436
assert_equal(masked_array(x, mask=m1, dtype=float_dtype).max(),
1437
float_dtype(a10))
1438
assert_equal(masked_array(x, mask=m1, dtype=float_dtype).min(),
1439
float_dtype(an10))
1440
1441
# Complex types only test
1442
for float_dtype in float_dtypes[-3:]:
1443
ym = masked_array([1e20 + 1j, 1e20 - 2j, 1e20 - 1j], mask=[0, 1, 0],
1444
dtype=float_dtype)
1445
assert_equal(ym.min(), float_dtype(1e20 - 1j))
1446
assert_equal(ym.max(), float_dtype(1e20 + 1j))
1447
1448
zm = masked_array([np.inf + 2j, np.inf + 3j, -np.inf - 1j], mask=[0, 1, 0],
1449
dtype=float_dtype)
1450
assert_equal(zm.min(), float_dtype(-np.inf - 1j))
1451
assert_equal(zm.max(), float_dtype(np.inf + 2j))
1452
1453
cmax = np.inf - 1j * np.finfo(np.float64).max
1454
assert masked_array([-cmax, 0], mask=[0, 1]).max() == -cmax
1455
assert masked_array([cmax, 0], mask=[0, 1]).min() == cmax
1456
1457
@pytest.mark.parametrize("dtype", "bBiIqQ")
1458
@pytest.mark.parametrize("mask", [
1459
[False, False, False, True, True], # masked min/max
1460
[False, False, False, True, False], # masked max only
1461
[False, False, False, False, True], # masked min only
1462
])
1463
@pytest.mark.parametrize("axis", [None, -1])
1464
def test_minmax_ints(self, dtype, mask, axis):
1465
iinfo = np.iinfo(dtype)
1466
# two dimensional to hit certain filling paths
1467
a = np.array([[0, 10, -10, iinfo.min, iinfo.max]] * 2).astype(dtype)
1468
mask = np.asarray([mask] * 2)
1469
1470
masked_a = masked_array(a, mask=mask)
1471
assert_array_equal(masked_a.min(axis), a[~mask].min(axis))
1472
assert_array_equal(masked_a.max(axis), a[~mask].max(axis))
1473
1474
@pytest.mark.parametrize("time_type", ["M8[s]", "m8[s]"])
1475
def test_minmax_time_dtypes(self, time_type):
1476
def minmax_with_mask(arr, mask):
1477
masked_arr = masked_array(arr, mask=mask)
1478
expected_min = arr[~np.array(mask, dtype=bool)].min()
1479
expected_max = arr[~np.array(mask, dtype=bool)].max()
1480
1481
assert_array_equal(masked_arr.min(), expected_min)
1482
assert_array_equal(masked_arr.max(), expected_max)
1483
1484
# Additional tests on max/min for time dtypes
1485
x1 = np.array([1, 1, -2, 4, 5, -10, 10, 1, 2, -2**63 + 1], dtype=time_type)
1486
x2 = np.array(['NaT', 1, -2, 4, 5, -10, 10, 1, 2, 3], dtype=time_type)
1487
x3 = np.array(['NaT', 'NaT', -2, 4, 5, -10, 10, 1, 2, 3], dtype=time_type)
1488
x_test = [x1, x2, x3]
1489
m = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0]
1490
1491
for x in x_test:
1492
minmax_with_mask(x, m)
1493
1494
def test_addsumprod(self):
1495
# Tests add, sum, product.
1496
x, y, _, _, _, xm, ym, _, _, _ = self._create_data()
1497
assert_equal(np.add.reduce(x), add.reduce(x))
1498
assert_equal(np.add.accumulate(x), add.accumulate(x))
1499
assert_equal(4, sum(array(4), axis=0))
1500
assert_equal(4, sum(array(4), axis=0))
1501
assert_equal(np.sum(x, axis=0), sum(x, axis=0))
1502
assert_equal(np.sum(filled(xm, 0), axis=0), sum(xm, axis=0))
1503
assert_equal(np.sum(x, 0), sum(x, 0))
1504
assert_equal(np.prod(x, axis=0), product(x, axis=0))
1505
assert_equal(np.prod(x, 0), product(x, 0))
1506
assert_equal(np.prod(filled(xm, 1), axis=0), product(xm, axis=0))
1507
s = (3, 4)
1508
x.shape = y.shape = xm.shape = ym.shape = s
1509
if len(s) > 1:
1510
assert_equal(np.concatenate((x, y), 1), concatenate((xm, ym), 1))
1511
assert_equal(np.add.reduce(x, 1), add.reduce(x, 1))
1512
assert_equal(np.sum(x, 1), sum(x, 1))
1513
assert_equal(np.prod(x, 1), product(x, 1))
1514
1515
def test_binops_d2D(self):
1516
# Test binary operations on 2D data
1517
a = array([[1.], [2.], [3.]], mask=[[False], [True], [True]])
1518
b = array([[2., 3.], [4., 5.], [6., 7.]])
1519
1520
test = a * b
1521
control = array([[2., 3.], [2., 2.], [3., 3.]],
1522
mask=[[0, 0], [1, 1], [1, 1]])
1523
assert_equal(test, control)
1524
assert_equal(test.data, control.data)
1525
assert_equal(test.mask, control.mask)
1526
1527
test = b * a
1528
control = array([[2., 3.], [4., 5.], [6., 7.]],
1529
mask=[[0, 0], [1, 1], [1, 1]])
1530
assert_equal(test, control)
1531
assert_equal(test.data, control.data)
1532
assert_equal(test.mask, control.mask)
1533
1534
a = array([[1.], [2.], [3.]])
1535
b = array([[2., 3.], [4., 5.], [6., 7.]],
1536
mask=[[0, 0], [0, 0], [0, 1]])
1537
test = a * b
1538
control = array([[2, 3], [8, 10], [18, 3]],
1539
mask=[[0, 0], [0, 0], [0, 1]])
1540
assert_equal(test, control)
1541
assert_equal(test.data, control.data)
1542
assert_equal(test.mask, control.mask)
1543
1544
test = b * a
1545
control = array([[2, 3], [8, 10], [18, 7]],
1546
mask=[[0, 0], [0, 0], [0, 1]])
1547
assert_equal(test, control)
1548
assert_equal(test.data, control.data)
1549
assert_equal(test.mask, control.mask)
1550
1551
def test_domained_binops_d2D(self):
1552
# Test domained binary operations on 2D data
1553
a = array([[1.], [2.], [3.]], mask=[[False], [True], [True]])
1554
b = array([[2., 3.], [4., 5.], [6., 7.]])
1555
1556
test = a / b
1557
control = array([[1. / 2., 1. / 3.], [2., 2.], [3., 3.]],
1558
mask=[[0, 0], [1, 1], [1, 1]])
1559
assert_equal(test, control)
1560
assert_equal(test.data, control.data)
1561
assert_equal(test.mask, control.mask)
1562
1563
test = b / a
1564
control = array([[2. / 1., 3. / 1.], [4., 5.], [6., 7.]],
1565
mask=[[0, 0], [1, 1], [1, 1]])
1566
assert_equal(test, control)
1567
assert_equal(test.data, control.data)
1568
assert_equal(test.mask, control.mask)
1569
1570
a = array([[1.], [2.], [3.]])
1571
b = array([[2., 3.], [4., 5.], [6., 7.]],
1572
mask=[[0, 0], [0, 0], [0, 1]])
1573
test = a / b
1574
control = array([[1. / 2, 1. / 3], [2. / 4, 2. / 5], [3. / 6, 3]],
1575
mask=[[0, 0], [0, 0], [0, 1]])
1576
assert_equal(test, control)
1577
assert_equal(test.data, control.data)
1578
assert_equal(test.mask, control.mask)
1579
1580
test = b / a
1581
control = array([[2 / 1., 3 / 1.], [4 / 2., 5 / 2.], [6 / 3., 7]],
1582
mask=[[0, 0], [0, 0], [0, 1]])
1583
assert_equal(test, control)
1584
assert_equal(test.data, control.data)
1585
assert_equal(test.mask, control.mask)
1586
1587
def test_noshrinking(self):
1588
# Check that we don't shrink a mask when not wanted
1589
# Binary operations
1590
a = masked_array([1., 2., 3.], mask=[False, False, False],
1591
shrink=False)
1592
b = a + 1
1593
assert_equal(b.mask, [0, 0, 0])
1594
# In place binary operation
1595
a += 1
1596
assert_equal(a.mask, [0, 0, 0])
1597
# Domained binary operation
1598
b = a / 1.
1599
assert_equal(b.mask, [0, 0, 0])
1600
# In place binary operation
1601
a /= 1.
1602
assert_equal(a.mask, [0, 0, 0])
1603
1604
def test_ufunc_nomask(self):
1605
# check the case ufuncs should set the mask to false
1606
m = np.ma.array([1])
1607
# check we don't get array([False], dtype=bool)
1608
assert_equal(np.true_divide(m, 5).mask.shape, ())
1609
1610
def test_noshink_on_creation(self):
1611
# Check that the mask is not shrunk on array creation when not wanted
1612
a = np.ma.masked_values([1., 2.5, 3.1], 1.5, shrink=False)
1613
assert_equal(a.mask, [0, 0, 0])
1614
1615
def test_mod(self):
1616
# Tests mod
1617
x, y, _, _, _, xm, ym, _, _, _ = self._create_data()
1618
assert_equal(mod(x, y), mod(xm, ym))
1619
test = mod(ym, xm)
1620
assert_equal(test, np.mod(ym, xm))
1621
assert_equal(test.mask, mask_or(xm.mask, ym.mask))
1622
test = mod(xm, ym)
1623
assert_equal(test, np.mod(xm, ym))
1624
assert_equal(test.mask, mask_or(mask_or(xm.mask, ym.mask), (ym == 0)))
1625
1626
def test_TakeTransposeInnerOuter(self):
1627
# Test of take, transpose, inner, outer products
1628
x = arange(24)
1629
y = np.arange(24)
1630
x[5:6] = masked
1631
x = x.reshape(2, 3, 4)
1632
y = y.reshape(2, 3, 4)
1633
assert_equal(np.transpose(y, (2, 0, 1)), transpose(x, (2, 0, 1)))
1634
assert_equal(np.take(y, (2, 0, 1), 1), take(x, (2, 0, 1), 1))
1635
assert_equal(np.inner(filled(x, 0), filled(y, 0)),
1636
inner(x, y))
1637
assert_equal(np.outer(filled(x, 0), filled(y, 0)),
1638
outer(x, y))
1639
y = array(['abc', 1, 'def', 2, 3], object)
1640
y[2] = masked
1641
t = take(y, [0, 3, 4])
1642
assert_(t[0] == 'abc')
1643
assert_(t[1] == 2)
1644
assert_(t[2] == 3)
1645
1646
def test_imag_real(self):
1647
# Check complex
1648
xx = array([1 + 10j, 20 + 2j], mask=[1, 0])
1649
assert_equal(xx.imag, [10, 2])
1650
assert_equal(xx.imag.filled(), [1e+20, 2])
1651
assert_equal(xx.imag.dtype, xx._data.imag.dtype)
1652
assert_equal(xx.real, [1, 20])
1653
assert_equal(xx.real.filled(), [1e+20, 20])
1654
assert_equal(xx.real.dtype, xx._data.real.dtype)
1655
1656
def test_methods_with_output(self):
1657
xm = array(np.random.uniform(0, 10, 12)).reshape(3, 4)
1658
xm[:, 0] = xm[0] = xm[-1, -1] = masked
1659
1660
funclist = ('sum', 'prod', 'var', 'std', 'max', 'min', 'ptp', 'mean',)
1661
1662
for funcname in funclist:
1663
npfunc = getattr(np, funcname)
1664
xmmeth = getattr(xm, funcname)
1665
# A ndarray as explicit input
1666
output = np.empty(4, dtype=float)
1667
output.fill(-9999)
1668
result = npfunc(xm, axis=0, out=output)
1669
# ... the result should be the given output
1670
assert_(result is output)
1671
assert_equal(result, xmmeth(axis=0, out=output))
1672
1673
output = empty(4, dtype=int)
1674
result = xmmeth(axis=0, out=output)
1675
assert_(result is output)
1676
assert_(output[0] is masked)
1677
1678
def test_eq_on_structured(self):
1679
# Test the equality of structured arrays
1680
ndtype = [('A', int), ('B', int)]
1681
a = array([(1, 1), (2, 2)], mask=[(0, 1), (0, 0)], dtype=ndtype)
1682
1683
test = (a == a)
1684
assert_equal(test.data, [True, True])
1685
assert_equal(test.mask, [False, False])
1686
assert_(test.fill_value == True)
1687
1688
test = (a == a[0])
1689
assert_equal(test.data, [True, False])
1690
assert_equal(test.mask, [False, False])
1691
assert_(test.fill_value == True)
1692
1693
b = array([(1, 1), (2, 2)], mask=[(1, 0), (0, 0)], dtype=ndtype)
1694
test = (a == b)
1695
assert_equal(test.data, [False, True])
1696
assert_equal(test.mask, [True, False])
1697
assert_(test.fill_value == True)
1698
1699
test = (a[0] == b)
1700
assert_equal(test.data, [False, False])
1701
assert_equal(test.mask, [True, False])
1702
assert_(test.fill_value == True)
1703
1704
b = array([(1, 1), (2, 2)], mask=[(0, 1), (1, 0)], dtype=ndtype)
1705
test = (a == b)
1706
assert_equal(test.data, [True, True])
1707
assert_equal(test.mask, [False, False])
1708
assert_(test.fill_value == True)
1709
1710
# complicated dtype, 2-dimensional array.
1711
ndtype = [('A', int), ('B', [('BA', int), ('BB', int)])]
1712
a = array([[(1, (1, 1)), (2, (2, 2))],
1713
[(3, (3, 3)), (4, (4, 4))]],
1714
mask=[[(0, (1, 0)), (0, (0, 1))],
1715
[(1, (0, 0)), (1, (1, 1))]], dtype=ndtype)
1716
test = (a[0, 0] == a)
1717
assert_equal(test.data, [[True, False], [False, False]])
1718
assert_equal(test.mask, [[False, False], [False, True]])
1719
assert_(test.fill_value == True)
1720
1721
def test_ne_on_structured(self):
1722
# Test the equality of structured arrays
1723
ndtype = [('A', int), ('B', int)]
1724
a = array([(1, 1), (2, 2)], mask=[(0, 1), (0, 0)], dtype=ndtype)
1725
1726
test = (a != a)
1727
assert_equal(test.data, [False, False])
1728
assert_equal(test.mask, [False, False])
1729
assert_(test.fill_value == True)
1730
1731
test = (a != a[0])
1732
assert_equal(test.data, [False, True])
1733
assert_equal(test.mask, [False, False])
1734
assert_(test.fill_value == True)
1735
1736
b = array([(1, 1), (2, 2)], mask=[(1, 0), (0, 0)], dtype=ndtype)
1737
test = (a != b)
1738
assert_equal(test.data, [True, False])
1739
assert_equal(test.mask, [True, False])
1740
assert_(test.fill_value == True)
1741
1742
test = (a[0] != b)
1743
assert_equal(test.data, [True, True])
1744
assert_equal(test.mask, [True, False])
1745
assert_(test.fill_value == True)
1746
1747
b = array([(1, 1), (2, 2)], mask=[(0, 1), (1, 0)], dtype=ndtype)
1748
test = (a != b)
1749
assert_equal(test.data, [False, False])
1750
assert_equal(test.mask, [False, False])
1751
assert_(test.fill_value == True)
1752
1753
# complicated dtype, 2-dimensional array.
1754
ndtype = [('A', int), ('B', [('BA', int), ('BB', int)])]
1755
a = array([[(1, (1, 1)), (2, (2, 2))],
1756
[(3, (3, 3)), (4, (4, 4))]],
1757
mask=[[(0, (1, 0)), (0, (0, 1))],
1758
[(1, (0, 0)), (1, (1, 1))]], dtype=ndtype)
1759
test = (a[0, 0] != a)
1760
assert_equal(test.data, [[False, True], [True, True]])
1761
assert_equal(test.mask, [[False, False], [False, True]])
1762
assert_(test.fill_value == True)
1763
1764
def test_eq_ne_structured_with_non_masked(self):
1765
a = array([(1, 1), (2, 2), (3, 4)],
1766
mask=[(0, 1), (0, 0), (1, 1)], dtype='i4,i4')
1767
eq = a == a.data
1768
ne = a.data != a
1769
# Test the obvious.
1770
assert_(np.all(eq))
1771
assert_(not np.any(ne))
1772
# Expect the mask set only for items with all fields masked.
1773
expected_mask = a.mask == np.ones((), a.mask.dtype)
1774
assert_array_equal(eq.mask, expected_mask)
1775
assert_array_equal(ne.mask, expected_mask)
1776
# The masked element will indicated not equal, because the
1777
# masks did not match.
1778
assert_equal(eq.data, [True, True, False])
1779
assert_array_equal(eq.data, ~ne.data)
1780
1781
def test_eq_ne_structured_extra(self):
1782
# ensure simple examples are symmetric and make sense.
1783
# from https://github.com/numpy/numpy/pull/8590#discussion_r101126465
1784
dt = np.dtype('i4,i4')
1785
for m1 in (mvoid((1, 2), mask=(0, 0), dtype=dt),
1786
mvoid((1, 2), mask=(0, 1), dtype=dt),
1787
mvoid((1, 2), mask=(1, 0), dtype=dt),
1788
mvoid((1, 2), mask=(1, 1), dtype=dt)):
1789
ma1 = m1.view(MaskedArray)
1790
r1 = ma1.view('2i4')
1791
for m2 in (np.array((1, 1), dtype=dt),
1792
mvoid((1, 1), dtype=dt),
1793
mvoid((1, 0), mask=(0, 1), dtype=dt),
1794
mvoid((3, 2), mask=(0, 1), dtype=dt)):
1795
ma2 = m2.view(MaskedArray)
1796
r2 = ma2.view('2i4')
1797
eq_expected = (r1 == r2).all()
1798
assert_equal(m1 == m2, eq_expected)
1799
assert_equal(m2 == m1, eq_expected)
1800
assert_equal(ma1 == m2, eq_expected)
1801
assert_equal(m1 == ma2, eq_expected)
1802
assert_equal(ma1 == ma2, eq_expected)
1803
# Also check it is the same if we do it element by element.
1804
el_by_el = [m1[name] == m2[name] for name in dt.names]
1805
assert_equal(array(el_by_el, dtype=bool).all(), eq_expected)
1806
ne_expected = (r1 != r2).any()
1807
assert_equal(m1 != m2, ne_expected)
1808
assert_equal(m2 != m1, ne_expected)
1809
assert_equal(ma1 != m2, ne_expected)
1810
assert_equal(m1 != ma2, ne_expected)
1811
assert_equal(ma1 != ma2, ne_expected)
1812
el_by_el = [m1[name] != m2[name] for name in dt.names]
1813
assert_equal(array(el_by_el, dtype=bool).any(), ne_expected)
1814
1815
@pytest.mark.parametrize('dt', ['S', 'U', 'T'])
1816
@pytest.mark.parametrize('fill', [None, 'A'])
1817
def test_eq_for_strings(self, dt, fill):
1818
# Test the equality of structured arrays
1819
a = array(['a', 'b'], dtype=dt, mask=[0, 1], fill_value=fill)
1820
1821
test = (a == a)
1822
assert_equal(test.data, [True, True])
1823
assert_equal(test.mask, [False, True])
1824
assert_(test.fill_value == True)
1825
1826
test = (a == a[0])
1827
assert_equal(test.data, [True, False])
1828
assert_equal(test.mask, [False, True])
1829
assert_(test.fill_value == True)
1830
1831
b = array(['a', 'b'], dtype=dt, mask=[1, 0], fill_value=fill)
1832
test = (a == b)
1833
assert_equal(test.data, [False, False])
1834
assert_equal(test.mask, [True, True])
1835
assert_(test.fill_value == True)
1836
1837
test = (a[0] == b)
1838
assert_equal(test.data, [False, False])
1839
assert_equal(test.mask, [True, False])
1840
assert_(test.fill_value == True)
1841
1842
test = (b == a[0])
1843
assert_equal(test.data, [False, False])
1844
assert_equal(test.mask, [True, False])
1845
assert_(test.fill_value == True)
1846
1847
@pytest.mark.parametrize('dt', ['S', 'U', 'T'])
1848
@pytest.mark.parametrize('fill', [None, 'A'])
1849
def test_ne_for_strings(self, dt, fill):
1850
# Test the equality of structured arrays
1851
a = array(['a', 'b'], dtype=dt, mask=[0, 1], fill_value=fill)
1852
1853
test = (a != a)
1854
assert_equal(test.data, [False, False])
1855
assert_equal(test.mask, [False, True])
1856
assert_(test.fill_value == True)
1857
1858
test = (a != a[0])
1859
assert_equal(test.data, [False, True])
1860
assert_equal(test.mask, [False, True])
1861
assert_(test.fill_value == True)
1862
1863
b = array(['a', 'b'], dtype=dt, mask=[1, 0], fill_value=fill)
1864
test = (a != b)
1865
assert_equal(test.data, [True, True])
1866
assert_equal(test.mask, [True, True])
1867
assert_(test.fill_value == True)
1868
1869
test = (a[0] != b)
1870
assert_equal(test.data, [True, True])
1871
assert_equal(test.mask, [True, False])
1872
assert_(test.fill_value == True)
1873
1874
test = (b != a[0])
1875
assert_equal(test.data, [True, True])
1876
assert_equal(test.mask, [True, False])
1877
assert_(test.fill_value == True)
1878
1879
@pytest.mark.parametrize('dt1', num_dts, ids=num_ids)
1880
@pytest.mark.parametrize('dt2', num_dts, ids=num_ids)
1881
@pytest.mark.parametrize('fill', [None, 1])
1882
def test_eq_for_numeric(self, dt1, dt2, fill):
1883
# Test the equality of structured arrays
1884
a = array([0, 1], dtype=dt1, mask=[0, 1], fill_value=fill)
1885
1886
test = (a == a)
1887
assert_equal(test.data, [True, True])
1888
assert_equal(test.mask, [False, True])
1889
assert_(test.fill_value == True)
1890
1891
test = (a == a[0])
1892
assert_equal(test.data, [True, False])
1893
assert_equal(test.mask, [False, True])
1894
assert_(test.fill_value == True)
1895
1896
b = array([0, 1], dtype=dt2, mask=[1, 0], fill_value=fill)
1897
test = (a == b)
1898
assert_equal(test.data, [False, False])
1899
assert_equal(test.mask, [True, True])
1900
assert_(test.fill_value == True)
1901
1902
test = (a[0] == b)
1903
assert_equal(test.data, [False, False])
1904
assert_equal(test.mask, [True, False])
1905
assert_(test.fill_value == True)
1906
1907
test = (b == a[0])
1908
assert_equal(test.data, [False, False])
1909
assert_equal(test.mask, [True, False])
1910
assert_(test.fill_value == True)
1911
1912
@pytest.mark.parametrize("op", [operator.eq, operator.lt])
1913
def test_eq_broadcast_with_unmasked(self, op):
1914
a = array([0, 1], mask=[0, 1])
1915
b = np.arange(10).reshape(5, 2)
1916
result = op(a, b)
1917
assert_(result.mask.shape == b.shape)
1918
assert_equal(result.mask, np.zeros(b.shape, bool) | a.mask)
1919
1920
@pytest.mark.parametrize("op", [operator.eq, operator.gt])
1921
def test_comp_no_mask_not_broadcast(self, op):
1922
# Regression test for failing doctest in MaskedArray.nonzero
1923
# after gh-24556.
1924
a = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
1925
result = op(a, 3)
1926
assert_(not result.mask.shape)
1927
assert_(result.mask is nomask)
1928
1929
@pytest.mark.parametrize('dt1', num_dts, ids=num_ids)
1930
@pytest.mark.parametrize('dt2', num_dts, ids=num_ids)
1931
@pytest.mark.parametrize('fill', [None, 1])
1932
def test_ne_for_numeric(self, dt1, dt2, fill):
1933
# Test the equality of structured arrays
1934
a = array([0, 1], dtype=dt1, mask=[0, 1], fill_value=fill)
1935
1936
test = (a != a)
1937
assert_equal(test.data, [False, False])
1938
assert_equal(test.mask, [False, True])
1939
assert_(test.fill_value == True)
1940
1941
test = (a != a[0])
1942
assert_equal(test.data, [False, True])
1943
assert_equal(test.mask, [False, True])
1944
assert_(test.fill_value == True)
1945
1946
b = array([0, 1], dtype=dt2, mask=[1, 0], fill_value=fill)
1947
test = (a != b)
1948
assert_equal(test.data, [True, True])
1949
assert_equal(test.mask, [True, True])
1950
assert_(test.fill_value == True)
1951
1952
test = (a[0] != b)
1953
assert_equal(test.data, [True, True])
1954
assert_equal(test.mask, [True, False])
1955
assert_(test.fill_value == True)
1956
1957
test = (b != a[0])
1958
assert_equal(test.data, [True, True])
1959
assert_equal(test.mask, [True, False])
1960
assert_(test.fill_value == True)
1961
1962
@pytest.mark.parametrize('dt1', num_dts, ids=num_ids)
1963
@pytest.mark.parametrize('dt2', num_dts, ids=num_ids)
1964
@pytest.mark.parametrize('fill', [None, 1])
1965
@pytest.mark.parametrize('op',
1966
[operator.le, operator.lt, operator.ge, operator.gt])
1967
def test_comparisons_for_numeric(self, op, dt1, dt2, fill):
1968
# Test the equality of structured arrays
1969
a = array([0, 1], dtype=dt1, mask=[0, 1], fill_value=fill)
1970
1971
test = op(a, a)
1972
assert_equal(test.data, op(a._data, a._data))
1973
assert_equal(test.mask, [False, True])
1974
assert_(test.fill_value == True)
1975
1976
test = op(a, a[0])
1977
assert_equal(test.data, op(a._data, a._data[0]))
1978
assert_equal(test.mask, [False, True])
1979
assert_(test.fill_value == True)
1980
1981
b = array([0, 1], dtype=dt2, mask=[1, 0], fill_value=fill)
1982
test = op(a, b)
1983
assert_equal(test.data, op(a._data, b._data))
1984
assert_equal(test.mask, [True, True])
1985
assert_(test.fill_value == True)
1986
1987
test = op(a[0], b)
1988
assert_equal(test.data, op(a._data[0], b._data))
1989
assert_equal(test.mask, [True, False])
1990
assert_(test.fill_value == True)
1991
1992
test = op(b, a[0])
1993
assert_equal(test.data, op(b._data, a._data[0]))
1994
assert_equal(test.mask, [True, False])
1995
assert_(test.fill_value == True)
1996
1997
@pytest.mark.parametrize('dt', ['S', 'U', 'T'])
1998
@pytest.mark.parametrize('op',
1999
[operator.le, operator.lt, operator.ge, operator.gt])
2000
@pytest.mark.parametrize('fill', [None, "N/A"])
2001
def test_comparisons_strings(self, dt, op, fill):
2002
# See gh-21770, mask propagation is broken for strings (and some other
2003
# cases) so we explicitly test strings here.
2004
# In principle only == and != may need special handling...
2005
ma1 = masked_array(["a", "b", "cde"], mask=[0, 1, 0], fill_value=fill, dtype=dt)
2006
ma2 = masked_array(["cde", "b", "a"], mask=[0, 1, 0], fill_value=fill, dtype=dt)
2007
assert_equal(op(ma1, ma2)._data, op(ma1._data, ma2._data))
2008
2009
if isinstance(fill, str):
2010
fill = np.array(fill, dtype=dt)
2011
2012
ma1 = masked_array(["a", "b", "cde"], mask=[0, 1, 0], fill_value=fill, dtype=dt)
2013
ma2 = masked_array(["cde", "b", "a"], mask=[0, 1, 0], fill_value=fill, dtype=dt)
2014
assert_equal(op(ma1, ma2)._data, op(ma1._data, ma2._data))
2015
2016
@pytest.mark.filterwarnings("ignore:.*Comparison to `None`.*:FutureWarning")
2017
def test_eq_with_None(self):
2018
# Really, comparisons with None should not be done, but check them
2019
# anyway. Note that pep8 will flag these tests.
2020
# Deprecation is in place for arrays, and when it happens this
2021
# test will fail (and have to be changed accordingly).
2022
2023
# With partial mask
2024
a = array([None, 1], mask=[0, 1])
2025
assert_equal(a == None, array([True, False], mask=[0, 1])) # noqa: E711
2026
assert_equal(a.data == None, [True, False]) # noqa: E711
2027
assert_equal(a != None, array([False, True], mask=[0, 1])) # noqa: E711
2028
# With nomask
2029
a = array([None, 1], mask=False)
2030
assert_equal(a == None, [True, False]) # noqa: E711
2031
assert_equal(a != None, [False, True]) # noqa: E711
2032
# With complete mask
2033
a = array([None, 2], mask=True)
2034
assert_equal(a == None, array([False, True], mask=True)) # noqa: E711
2035
assert_equal(a != None, array([True, False], mask=True)) # noqa: E711
2036
# Fully masked, even comparison to None should return "masked"
2037
a = masked
2038
assert_equal(a == None, masked) # noqa: E711
2039
2040
def test_eq_with_scalar(self):
2041
a = array(1)
2042
assert_equal(a == 1, True)
2043
assert_equal(a == 0, False)
2044
assert_equal(a != 1, False)
2045
assert_equal(a != 0, True)
2046
b = array(1, mask=True)
2047
assert_equal(b == 0, masked)
2048
assert_equal(b == 1, masked)
2049
assert_equal(b != 0, masked)
2050
assert_equal(b != 1, masked)
2051
2052
def test_eq_different_dimensions(self):
2053
m1 = array([1, 1], mask=[0, 1])
2054
# test comparison with both masked and regular arrays.
2055
for m2 in (array([[0, 1], [1, 2]]),
2056
np.array([[0, 1], [1, 2]])):
2057
test = (m1 == m2)
2058
assert_equal(test.data, [[False, False],
2059
[True, False]])
2060
assert_equal(test.mask, [[False, True],
2061
[False, True]])
2062
2063
def test_numpyarithmetic(self):
2064
# Check that the mask is not back-propagated when using numpy functions
2065
a = masked_array([-1, 0, 1, 2, 3], mask=[0, 0, 0, 0, 1])
2066
control = masked_array([np.nan, np.nan, 0, np.log(2), -1],
2067
mask=[1, 1, 0, 0, 1])
2068
2069
test = log(a)
2070
assert_equal(test, control)
2071
assert_equal(test.mask, control.mask)
2072
assert_equal(a.mask, [0, 0, 0, 0, 1])
2073
2074
test = np.log(a)
2075
assert_equal(test, control)
2076
assert_equal(test.mask, control.mask)
2077
assert_equal(a.mask, [0, 0, 0, 0, 1])
2078
2079
2080
class TestMaskedArrayAttributes:
2081
2082
def test_keepmask(self):
2083
# Tests the keep mask flag
2084
x = masked_array([1, 2, 3], mask=[1, 0, 0])
2085
mx = masked_array(x)
2086
assert_equal(mx.mask, x.mask)
2087
mx = masked_array(x, mask=[0, 1, 0], keep_mask=False)
2088
assert_equal(mx.mask, [0, 1, 0])
2089
mx = masked_array(x, mask=[0, 1, 0], keep_mask=True)
2090
assert_equal(mx.mask, [1, 1, 0])
2091
# We default to true
2092
mx = masked_array(x, mask=[0, 1, 0])
2093
assert_equal(mx.mask, [1, 1, 0])
2094
2095
def test_hardmask(self):
2096
# Test hard_mask
2097
d = arange(5)
2098
n = [0, 0, 0, 1, 1]
2099
m = make_mask(n)
2100
xh = array(d, mask=m, hard_mask=True)
2101
# We need to copy, to avoid updating d in xh !
2102
xs = array(d, mask=m, hard_mask=False, copy=True)
2103
xh[[1, 4]] = [10, 40]
2104
xs[[1, 4]] = [10, 40]
2105
assert_equal(xh._data, [0, 10, 2, 3, 4])
2106
assert_equal(xs._data, [0, 10, 2, 3, 40])
2107
assert_equal(xs.mask, [0, 0, 0, 1, 0])
2108
assert_(xh._hardmask)
2109
assert_(not xs._hardmask)
2110
xh[1:4] = [10, 20, 30]
2111
xs[1:4] = [10, 20, 30]
2112
assert_equal(xh._data, [0, 10, 20, 3, 4])
2113
assert_equal(xs._data, [0, 10, 20, 30, 40])
2114
assert_equal(xs.mask, nomask)
2115
xh[0] = masked
2116
xs[0] = masked
2117
assert_equal(xh.mask, [1, 0, 0, 1, 1])
2118
assert_equal(xs.mask, [1, 0, 0, 0, 0])
2119
xh[:] = 1
2120
xs[:] = 1
2121
assert_equal(xh._data, [0, 1, 1, 3, 4])
2122
assert_equal(xs._data, [1, 1, 1, 1, 1])
2123
assert_equal(xh.mask, [1, 0, 0, 1, 1])
2124
assert_equal(xs.mask, nomask)
2125
# Switch to soft mask
2126
xh.soften_mask()
2127
xh[:] = arange(5)
2128
assert_equal(xh._data, [0, 1, 2, 3, 4])
2129
assert_equal(xh.mask, nomask)
2130
# Switch back to hard mask
2131
xh.harden_mask()
2132
xh[xh < 3] = masked
2133
assert_equal(xh._data, [0, 1, 2, 3, 4])
2134
assert_equal(xh._mask, [1, 1, 1, 0, 0])
2135
xh[filled(xh > 1, False)] = 5
2136
assert_equal(xh._data, [0, 1, 2, 5, 5])
2137
assert_equal(xh._mask, [1, 1, 1, 0, 0])
2138
2139
xh = array([[1, 2], [3, 4]], mask=[[1, 0], [0, 0]], hard_mask=True)
2140
xh[0] = 0
2141
assert_equal(xh._data, [[1, 0], [3, 4]])
2142
assert_equal(xh._mask, [[1, 0], [0, 0]])
2143
xh[-1, -1] = 5
2144
assert_equal(xh._data, [[1, 0], [3, 5]])
2145
assert_equal(xh._mask, [[1, 0], [0, 0]])
2146
xh[filled(xh < 5, False)] = 2
2147
assert_equal(xh._data, [[1, 2], [2, 5]])
2148
assert_equal(xh._mask, [[1, 0], [0, 0]])
2149
2150
def test_hardmask_again(self):
2151
# Another test of hardmask
2152
d = arange(5)
2153
n = [0, 0, 0, 1, 1]
2154
m = make_mask(n)
2155
xh = array(d, mask=m, hard_mask=True)
2156
xh[4:5] = 999
2157
xh[0:1] = 999
2158
assert_equal(xh._data, [999, 1, 2, 3, 4])
2159
2160
def test_hardmask_oncemore_yay(self):
2161
# OK, yet another test of hardmask
2162
# Make sure that harden_mask/soften_mask//unshare_mask returns self
2163
a = array([1, 2, 3], mask=[1, 0, 0])
2164
b = a.harden_mask()
2165
assert_equal(a, b)
2166
b[0] = 0
2167
assert_equal(a, b)
2168
assert_equal(b, array([1, 2, 3], mask=[1, 0, 0]))
2169
a = b.soften_mask()
2170
a[0] = 0
2171
assert_equal(a, b)
2172
assert_equal(b, array([0, 2, 3], mask=[0, 0, 0]))
2173
2174
def test_smallmask(self):
2175
# Checks the behaviour of _smallmask
2176
a = arange(10)
2177
a[1] = masked
2178
a[1] = 1
2179
assert_equal(a._mask, nomask)
2180
a = arange(10)
2181
a._smallmask = False
2182
a[1] = masked
2183
a[1] = 1
2184
assert_equal(a._mask, zeros(10))
2185
2186
def test_shrink_mask(self):
2187
# Tests .shrink_mask()
2188
a = array([1, 2, 3], mask=[0, 0, 0])
2189
b = a.shrink_mask()
2190
assert_equal(a, b)
2191
assert_equal(a.mask, nomask)
2192
2193
# Mask cannot be shrunk on structured types, so is a no-op
2194
a = np.ma.array([(1, 2.0)], [('a', int), ('b', float)])
2195
b = a.copy()
2196
a.shrink_mask()
2197
assert_equal(a.mask, b.mask)
2198
2199
def test_flat(self):
2200
# Test that flat can return all types of items [#4585, #4615]
2201
# test 2-D record array
2202
# ... on structured array w/ masked records
2203
x = array([[(1, 1.1, 'one'), (2, 2.2, 'two'), (3, 3.3, 'thr')],
2204
[(4, 4.4, 'fou'), (5, 5.5, 'fiv'), (6, 6.6, 'six')]],
2205
dtype=[('a', int), ('b', float), ('c', '|S8')])
2206
x['a'][0, 1] = masked
2207
x['b'][1, 0] = masked
2208
x['c'][0, 2] = masked
2209
x[-1, -1] = masked
2210
xflat = x.flat
2211
assert_equal(xflat[0], x[0, 0])
2212
assert_equal(xflat[1], x[0, 1])
2213
assert_equal(xflat[2], x[0, 2])
2214
assert_equal(xflat[:3], x[0])
2215
assert_equal(xflat[3], x[1, 0])
2216
assert_equal(xflat[4], x[1, 1])
2217
assert_equal(xflat[5], x[1, 2])
2218
assert_equal(xflat[3:], x[1])
2219
assert_equal(xflat[-1], x[-1, -1])
2220
i = 0
2221
j = 0
2222
for xf in xflat:
2223
assert_equal(xf, x[j, i])
2224
i += 1
2225
if i >= x.shape[-1]:
2226
i = 0
2227
j += 1
2228
2229
def test_assign_dtype(self):
2230
# check that the mask's dtype is updated when dtype is changed
2231
a = np.zeros(4, dtype='f4,i4')
2232
2233
m = np.ma.array(a)
2234
m.dtype = np.dtype('f4')
2235
repr(m) # raises?
2236
assert_equal(m.dtype, np.dtype('f4'))
2237
2238
# check that dtype changes that change shape of mask too much
2239
# are not allowed
2240
def assign():
2241
m = np.ma.array(a)
2242
m.dtype = np.dtype('f8')
2243
assert_raises(ValueError, assign)
2244
2245
b = a.view(dtype='f4', type=np.ma.MaskedArray) # raises?
2246
assert_equal(b.dtype, np.dtype('f4'))
2247
2248
# check that nomask is preserved
2249
a = np.zeros(4, dtype='f4')
2250
m = np.ma.array(a)
2251
m.dtype = np.dtype('f4,i4')
2252
assert_equal(m.dtype, np.dtype('f4,i4'))
2253
assert_equal(m._mask, np.ma.nomask)
2254
2255
2256
class TestFillingValues:
2257
2258
def test_check_on_scalar(self):
2259
# Test _check_fill_value set to valid and invalid values
2260
_check_fill_value = np.ma.core._check_fill_value
2261
2262
fval = _check_fill_value(0, int)
2263
assert_equal(fval, 0)
2264
fval = _check_fill_value(None, int)
2265
assert_equal(fval, default_fill_value(0))
2266
2267
fval = _check_fill_value(0, "|S3")
2268
assert_equal(fval, b"0")
2269
fval = _check_fill_value(None, "|S3")
2270
assert_equal(fval, default_fill_value(b"camelot!"))
2271
assert_raises(TypeError, _check_fill_value, 1e+20, int)
2272
assert_raises(TypeError, _check_fill_value, 'stuff', int)
2273
2274
def test_check_on_fields(self):
2275
# Tests _check_fill_value with records
2276
_check_fill_value = np.ma.core._check_fill_value
2277
ndtype = [('a', int), ('b', float), ('c', "|S3")]
2278
# A check on a list should return a single record
2279
fval = _check_fill_value([-999, -12345678.9, "???"], ndtype)
2280
assert_(isinstance(fval, ndarray))
2281
assert_equal(fval.item(), [-999, -12345678.9, b"???"])
2282
# A check on None should output the defaults
2283
fval = _check_fill_value(None, ndtype)
2284
assert_(isinstance(fval, ndarray))
2285
assert_equal(fval.item(), [default_fill_value(0),
2286
default_fill_value(0.),
2287
asbytes(default_fill_value("0"))])
2288
#.....Using a structured type as fill_value should work
2289
fill_val = np.array((-999, -12345678.9, "???"), dtype=ndtype)
2290
fval = _check_fill_value(fill_val, ndtype)
2291
assert_(isinstance(fval, ndarray))
2292
assert_equal(fval.item(), [-999, -12345678.9, b"???"])
2293
2294
#.....Using a flexible type w/ a different type shouldn't matter
2295
# BEHAVIOR in 1.5 and earlier, and 1.13 and later: match structured
2296
# types by position
2297
fill_val = np.array((-999, -12345678.9, "???"),
2298
dtype=[("A", int), ("B", float), ("C", "|S3")])
2299
fval = _check_fill_value(fill_val, ndtype)
2300
assert_(isinstance(fval, ndarray))
2301
assert_equal(fval.item(), [-999, -12345678.9, b"???"])
2302
2303
#.....Using an object-array shouldn't matter either
2304
fill_val = np.ndarray(shape=(1,), dtype=object)
2305
fill_val[0] = (-999, -12345678.9, b"???")
2306
fval = _check_fill_value(fill_val, object)
2307
assert_(isinstance(fval, ndarray))
2308
assert_equal(fval.item(), [-999, -12345678.9, b"???"])
2309
# NOTE: This test was never run properly as "fill_value" rather than
2310
# "fill_val" was assigned. Written properly, it fails.
2311
#fill_val = np.array((-999, -12345678.9, "???"))
2312
#fval = _check_fill_value(fill_val, ndtype)
2313
#assert_(isinstance(fval, ndarray))
2314
#assert_equal(fval.item(), [-999, -12345678.9, b"???"])
2315
#.....One-field-only flexible type should work as well
2316
ndtype = [("a", int)]
2317
fval = _check_fill_value(-999999999, ndtype)
2318
assert_(isinstance(fval, ndarray))
2319
assert_equal(fval.item(), (-999999999,))
2320
2321
def test_fillvalue_conversion(self):
2322
# Tests the behavior of fill_value during conversion
2323
# We had a tailored comment to make sure special attributes are
2324
# properly dealt with
2325
a = array([b'3', b'4', b'5'])
2326
a._optinfo.update({'comment': "updated!"})
2327
2328
b = array(a, dtype=int)
2329
assert_equal(b._data, [3, 4, 5])
2330
assert_equal(b.fill_value, default_fill_value(0))
2331
2332
b = array(a, dtype=float)
2333
assert_equal(b._data, [3, 4, 5])
2334
assert_equal(b.fill_value, default_fill_value(0.))
2335
2336
b = a.astype(int)
2337
assert_equal(b._data, [3, 4, 5])
2338
assert_equal(b.fill_value, default_fill_value(0))
2339
assert_equal(b._optinfo['comment'], "updated!")
2340
2341
b = a.astype([('a', '|S3')])
2342
assert_equal(b['a']._data, a._data)
2343
assert_equal(b['a'].fill_value, a.fill_value)
2344
2345
def test_default_fill_value(self):
2346
# check all calling conventions
2347
f1 = default_fill_value(1.)
2348
f2 = default_fill_value(np.array(1.))
2349
f3 = default_fill_value(np.array(1.).dtype)
2350
assert_equal(f1, f2)
2351
assert_equal(f1, f3)
2352
2353
def test_default_fill_value_structured(self):
2354
fields = array([(1, 1, 1)],
2355
dtype=[('i', int), ('s', '|S8'), ('f', float)])
2356
2357
f1 = default_fill_value(fields)
2358
f2 = default_fill_value(fields.dtype)
2359
expected = np.array((default_fill_value(0),
2360
default_fill_value('0'),
2361
default_fill_value(0.)), dtype=fields.dtype)
2362
assert_equal(f1, expected)
2363
assert_equal(f2, expected)
2364
2365
def test_default_fill_value_void(self):
2366
dt = np.dtype([('v', 'V7')])
2367
f = default_fill_value(dt)
2368
assert_equal(f['v'], np.array(default_fill_value(dt['v']), dt['v']))
2369
2370
def test_fillvalue(self):
2371
# Yet more fun with the fill_value
2372
data = masked_array([1, 2, 3], fill_value=-999)
2373
series = data[[0, 2, 1]]
2374
assert_equal(series._fill_value, data._fill_value)
2375
2376
mtype = [('f', float), ('s', '|S3')]
2377
x = array([(1, 'a'), (2, 'b'), (pi, 'pi')], dtype=mtype)
2378
x.fill_value = 999
2379
assert_equal(x.fill_value.item(), [999., b'999'])
2380
assert_equal(x['f'].fill_value, 999)
2381
assert_equal(x['s'].fill_value, b'999')
2382
2383
x.fill_value = (9, '???')
2384
assert_equal(x.fill_value.item(), (9, b'???'))
2385
assert_equal(x['f'].fill_value, 9)
2386
assert_equal(x['s'].fill_value, b'???')
2387
2388
x = array([1, 2, 3.1])
2389
x.fill_value = 999
2390
assert_equal(np.asarray(x.fill_value).dtype, float)
2391
assert_equal(x.fill_value, 999.)
2392
assert_equal(x._fill_value, np.array(999.))
2393
2394
@pytest.mark.filterwarnings("ignore:.*Numpy has detected.*:FutureWarning")
2395
def test_subarray_fillvalue(self):
2396
# gh-10483 test multi-field index fill value
2397
fields = array([(1, 1, 1)],
2398
dtype=[('i', int), ('s', '|S8'), ('f', float)])
2399
subfields = fields[['i', 'f']]
2400
assert_equal(tuple(subfields.fill_value), (999999, 1.e+20))
2401
# test comparison does not raise:
2402
subfields[1:] == subfields[:-1]
2403
2404
def test_fillvalue_exotic_dtype(self):
2405
# Tests yet more exotic flexible dtypes
2406
_check_fill_value = np.ma.core._check_fill_value
2407
ndtype = [('i', int), ('s', '|S8'), ('f', float)]
2408
control = np.array((default_fill_value(0),
2409
default_fill_value('0'),
2410
default_fill_value(0.),),
2411
dtype=ndtype)
2412
assert_equal(_check_fill_value(None, ndtype), control)
2413
# The shape shouldn't matter
2414
ndtype = [('f0', float, (2, 2))]
2415
control = np.array((default_fill_value(0.),),
2416
dtype=[('f0', float)]).astype(ndtype)
2417
assert_equal(_check_fill_value(None, ndtype), control)
2418
control = np.array((0,), dtype=[('f0', float)]).astype(ndtype)
2419
assert_equal(_check_fill_value(0, ndtype), control)
2420
2421
ndtype = np.dtype("int, (2,3)float, float")
2422
control = np.array((default_fill_value(0),
2423
default_fill_value(0.),
2424
default_fill_value(0.),),
2425
dtype="int, float, float").astype(ndtype)
2426
test = _check_fill_value(None, ndtype)
2427
assert_equal(test, control)
2428
control = np.array((0, 0, 0), dtype="int, float, float").astype(ndtype)
2429
assert_equal(_check_fill_value(0, ndtype), control)
2430
# but when indexing, fill value should become scalar not tuple
2431
# See issue #6723
2432
M = masked_array(control)
2433
assert_equal(M["f1"].fill_value.ndim, 0)
2434
2435
def test_fillvalue_datetime_timedelta(self):
2436
# Test default fillvalue for datetime64 and timedelta64 types.
2437
# See issue #4476, this would return '?' which would cause errors
2438
# elsewhere
2439
2440
for timecode in ("as", "fs", "ps", "ns", "us", "ms", "s", "m",
2441
"h", "D", "W", "M", "Y"):
2442
control = numpy.datetime64("NaT", timecode)
2443
test = default_fill_value(numpy.dtype("<M8[" + timecode + "]"))
2444
np.testing.assert_equal(test, control)
2445
2446
control = numpy.timedelta64("NaT", timecode)
2447
test = default_fill_value(numpy.dtype("<m8[" + timecode + "]"))
2448
np.testing.assert_equal(test, control)
2449
2450
def test_extremum_fill_value(self):
2451
# Tests extremum fill values for flexible type.
2452
a = array([(1, (2, 3)), (4, (5, 6))],
2453
dtype=[('A', int), ('B', [('BA', int), ('BB', int)])])
2454
test = a.fill_value
2455
assert_equal(test.dtype, a.dtype)
2456
assert_equal(test['A'], default_fill_value(a['A']))
2457
assert_equal(test['B']['BA'], default_fill_value(a['B']['BA']))
2458
assert_equal(test['B']['BB'], default_fill_value(a['B']['BB']))
2459
2460
test = minimum_fill_value(a)
2461
assert_equal(test.dtype, a.dtype)
2462
assert_equal(test[0], minimum_fill_value(a['A']))
2463
assert_equal(test[1][0], minimum_fill_value(a['B']['BA']))
2464
assert_equal(test[1][1], minimum_fill_value(a['B']['BB']))
2465
assert_equal(test[1], minimum_fill_value(a['B']))
2466
2467
test = maximum_fill_value(a)
2468
assert_equal(test.dtype, a.dtype)
2469
assert_equal(test[0], maximum_fill_value(a['A']))
2470
assert_equal(test[1][0], maximum_fill_value(a['B']['BA']))
2471
assert_equal(test[1][1], maximum_fill_value(a['B']['BB']))
2472
assert_equal(test[1], maximum_fill_value(a['B']))
2473
2474
def test_extremum_fill_value_subdtype(self):
2475
a = array(([2, 3, 4],), dtype=[('value', np.int8, 3)])
2476
2477
test = minimum_fill_value(a)
2478
assert_equal(test.dtype, a.dtype)
2479
assert_equal(test[0], np.full(3, minimum_fill_value(a['value'])))
2480
2481
test = maximum_fill_value(a)
2482
assert_equal(test.dtype, a.dtype)
2483
assert_equal(test[0], np.full(3, maximum_fill_value(a['value'])))
2484
2485
def test_fillvalue_individual_fields(self):
2486
# Test setting fill_value on individual fields
2487
ndtype = [('a', int), ('b', int)]
2488
# Explicit fill_value
2489
a = array(list(zip([1, 2, 3], [4, 5, 6])),
2490
fill_value=(-999, -999), dtype=ndtype)
2491
aa = a['a']
2492
aa.set_fill_value(10)
2493
assert_equal(aa._fill_value, np.array(10))
2494
assert_equal(tuple(a.fill_value), (10, -999))
2495
a.fill_value['b'] = -10
2496
assert_equal(tuple(a.fill_value), (10, -10))
2497
# Implicit fill_value
2498
t = array(list(zip([1, 2, 3], [4, 5, 6])), dtype=ndtype)
2499
tt = t['a']
2500
tt.set_fill_value(10)
2501
assert_equal(tt._fill_value, np.array(10))
2502
assert_equal(tuple(t.fill_value), (10, default_fill_value(0)))
2503
2504
def test_fillvalue_implicit_structured_array(self):
2505
# Check that fill_value is always defined for structured arrays
2506
ndtype = ('b', float)
2507
adtype = ('a', float)
2508
a = array([(1.,), (2.,)], mask=[(False,), (False,)],
2509
fill_value=(np.nan,), dtype=np.dtype([adtype]))
2510
b = empty(a.shape, dtype=[adtype, ndtype])
2511
b['a'] = a['a']
2512
b['a'].set_fill_value(a['a'].fill_value)
2513
f = b._fill_value[()]
2514
assert_(np.isnan(f[0]))
2515
assert_equal(f[-1], default_fill_value(1.))
2516
2517
def test_fillvalue_as_arguments(self):
2518
# Test adding a fill_value parameter to empty/ones/zeros
2519
a = empty(3, fill_value=999.)
2520
assert_equal(a.fill_value, 999.)
2521
2522
a = ones(3, fill_value=999., dtype=float)
2523
assert_equal(a.fill_value, 999.)
2524
2525
a = zeros(3, fill_value=0., dtype=complex)
2526
assert_equal(a.fill_value, 0.)
2527
2528
a = identity(3, fill_value=0., dtype=complex)
2529
assert_equal(a.fill_value, 0.)
2530
2531
def test_shape_argument(self):
2532
# Test that shape can be provides as an argument
2533
# GH issue 6106
2534
a = empty(shape=(3, ))
2535
assert_equal(a.shape, (3, ))
2536
2537
a = ones(shape=(3, ), dtype=float)
2538
assert_equal(a.shape, (3, ))
2539
2540
a = zeros(shape=(3, ), dtype=complex)
2541
assert_equal(a.shape, (3, ))
2542
2543
def test_fillvalue_in_view(self):
2544
# Test the behavior of fill_value in view
2545
2546
# Create initial masked array
2547
x = array([1, 2, 3], fill_value=1, dtype=np.int64)
2548
2549
# Check that fill_value is preserved by default
2550
y = x.view()
2551
assert_(y.fill_value == 1)
2552
2553
# Check that fill_value is preserved if dtype is specified and the
2554
# dtype is an ndarray sub-class and has a _fill_value attribute
2555
y = x.view(MaskedArray)
2556
assert_(y.fill_value == 1)
2557
2558
# Check that fill_value is preserved if type is specified and the
2559
# dtype is an ndarray sub-class and has a _fill_value attribute (by
2560
# default, the first argument is dtype, not type)
2561
y = x.view(type=MaskedArray)
2562
assert_(y.fill_value == 1)
2563
2564
# Check that code does not crash if passed an ndarray sub-class that
2565
# does not have a _fill_value attribute
2566
y = x.view(np.ndarray)
2567
y = x.view(type=np.ndarray)
2568
2569
# Check that fill_value can be overridden with view
2570
y = x.view(MaskedArray, fill_value=2)
2571
assert_(y.fill_value == 2)
2572
2573
# Check that fill_value can be overridden with view (using type=)
2574
y = x.view(type=MaskedArray, fill_value=2)
2575
assert_(y.fill_value == 2)
2576
2577
# Check that fill_value gets reset if passed a dtype but not a
2578
# fill_value. This is because even though in some cases one can safely
2579
# cast the fill_value, e.g. if taking an int64 view of an int32 array,
2580
# in other cases, this cannot be done (e.g. int32 view of an int64
2581
# array with a large fill_value).
2582
y = x.view(dtype=np.int32)
2583
assert_(y.fill_value == 999999)
2584
2585
def test_fillvalue_bytes_or_str(self):
2586
# Test whether fill values work as expected for structured dtypes
2587
# containing bytes or str. See issue #7259.
2588
a = empty(shape=(3, ), dtype="(2,)3S,(2,)3U")
2589
assert_equal(a["f0"].fill_value, default_fill_value(b"spam"))
2590
assert_equal(a["f1"].fill_value, default_fill_value("eggs"))
2591
2592
2593
class TestUfuncs:
2594
# Test class for the application of ufuncs on MaskedArrays.
2595
def _create_data(self):
2596
# Base data definition.
2597
return (array([1.0, 0, -1, pi / 2] * 2, mask=[0, 1] + [0] * 6),
2598
array([1.0, 0, -1, pi / 2] * 2, mask=[1, 0] + [0] * 6),)
2599
2600
@pytest.fixture(autouse=True, scope="class")
2601
def err_status(self):
2602
err = np.geterr()
2603
np.seterr(divide='ignore', invalid='ignore')
2604
yield err
2605
np.seterr(**err)
2606
2607
def test_testUfuncRegression(self):
2608
# Tests new ufuncs on MaskedArrays.
2609
for f in ['sqrt', 'log', 'log10', 'exp', 'conjugate',
2610
'sin', 'cos', 'tan',
2611
'arcsin', 'arccos', 'arctan',
2612
'sinh', 'cosh', 'tanh',
2613
'arcsinh',
2614
'arccosh',
2615
'arctanh',
2616
'absolute', 'fabs', 'negative',
2617
'floor', 'ceil',
2618
'logical_not',
2619
'add', 'subtract', 'multiply',
2620
'divide', 'true_divide', 'floor_divide',
2621
'remainder', 'fmod', 'hypot', 'arctan2',
2622
'equal', 'not_equal', 'less_equal', 'greater_equal',
2623
'less', 'greater',
2624
'logical_and', 'logical_or', 'logical_xor',
2625
]:
2626
try:
2627
uf = getattr(umath, f)
2628
except AttributeError:
2629
uf = getattr(fromnumeric, f)
2630
mf = getattr(numpy.ma.core, f)
2631
args = self._create_data()[:uf.nin]
2632
ur = uf(*args)
2633
mr = mf(*args)
2634
assert_equal(ur.filled(0), mr.filled(0), f)
2635
assert_mask_equal(ur.mask, mr.mask, err_msg=f)
2636
2637
def test_reduce(self):
2638
# Tests reduce on MaskedArrays.
2639
a = self._create_data()[0]
2640
assert_(not alltrue(a, axis=0))
2641
assert_(sometrue(a, axis=0))
2642
assert_equal(sum(a[:3], axis=0), 0)
2643
assert_equal(product(a, axis=0), 0)
2644
assert_equal(add.reduce(a), pi)
2645
2646
def test_minmax(self):
2647
# Tests extrema on MaskedArrays.
2648
a = arange(1, 13).reshape(3, 4)
2649
amask = masked_where(a < 5, a)
2650
assert_equal(amask.max(), a.max())
2651
assert_equal(amask.min(), 5)
2652
assert_equal(amask.max(0), a.max(0))
2653
assert_equal(amask.min(0), [5, 6, 7, 8])
2654
assert_(amask.max(1)[0].mask)
2655
assert_(amask.min(1)[0].mask)
2656
2657
def test_ndarray_mask(self):
2658
# Check that the mask of the result is a ndarray (not a MaskedArray...)
2659
a = masked_array([-1, 0, 1, 2, 3], mask=[0, 0, 0, 0, 1])
2660
test = np.sqrt(a)
2661
control = masked_array([-1, 0, 1, np.sqrt(2), -1],
2662
mask=[1, 0, 0, 0, 1])
2663
assert_equal(test, control)
2664
assert_equal(test.mask, control.mask)
2665
assert_(not isinstance(test.mask, MaskedArray))
2666
2667
def test_treatment_of_NotImplemented(self):
2668
# Check that NotImplemented is returned at appropriate places
2669
2670
a = masked_array([1., 2.], mask=[1, 0])
2671
assert_raises(TypeError, operator.mul, a, "abc")
2672
assert_raises(TypeError, operator.truediv, a, "abc")
2673
2674
class MyClass:
2675
__array_priority__ = a.__array_priority__ + 1
2676
2677
def __mul__(self, other):
2678
return "My mul"
2679
2680
def __rmul__(self, other):
2681
return "My rmul"
2682
2683
me = MyClass()
2684
assert_(me * a == "My mul")
2685
assert_(a * me == "My rmul")
2686
2687
# and that __array_priority__ is respected
2688
class MyClass2:
2689
__array_priority__ = 100
2690
2691
def __mul__(self, other):
2692
return "Me2mul"
2693
2694
def __rmul__(self, other):
2695
return "Me2rmul"
2696
2697
def __rtruediv__(self, other):
2698
return "Me2rdiv"
2699
2700
me_too = MyClass2()
2701
assert_(a.__mul__(me_too) is NotImplemented)
2702
assert_(all(multiply.outer(a, me_too) == "Me2rmul"))
2703
assert_(a.__truediv__(me_too) is NotImplemented)
2704
assert_(me_too * a == "Me2mul")
2705
assert_(a * me_too == "Me2rmul")
2706
assert_(a / me_too == "Me2rdiv")
2707
2708
def test_no_masked_nan_warnings(self):
2709
# check that a nan in masked position does not
2710
# cause ufunc warnings
2711
2712
m = np.ma.array([0.5, np.nan], mask=[0, 1])
2713
2714
with warnings.catch_warnings():
2715
warnings.filterwarnings("error")
2716
2717
# test unary and binary ufuncs
2718
exp(m)
2719
add(m, 1)
2720
m > 0
2721
2722
# test different unary domains
2723
sqrt(m)
2724
log(m)
2725
tan(m)
2726
arcsin(m)
2727
arccos(m)
2728
arccosh(m)
2729
2730
# test binary domains
2731
divide(m, 2)
2732
2733
# also check that allclose uses ma ufuncs, to avoid warning
2734
allclose(m, 0.5)
2735
2736
def test_masked_array_underflow(self):
2737
x = np.arange(0, 3, 0.1)
2738
X = np.ma.array(x)
2739
with np.errstate(under="raise"):
2740
X2 = X / 2.0
2741
np.testing.assert_array_equal(X2, x / 2)
2742
2743
2744
class TestMaskedArrayInPlaceArithmetic:
2745
# Test MaskedArray Arithmetic
2746
def _create_intdata(self):
2747
x = arange(10)
2748
y = arange(10)
2749
xm = arange(10)
2750
xm[2] = masked
2751
return x, y, xm
2752
2753
def _create_floatdata(self):
2754
x, y, xm = self._create_intdata()
2755
return x.astype(float), y.astype(float), xm.astype(float)
2756
2757
def _create_otherdata(self):
2758
o = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
2759
othertypes = [np.dtype(_).type for _ in o]
2760
x, y, xm = self._create_intdata()
2761
uint8data = (
2762
x.astype(np.uint8),
2763
y.astype(np.uint8),
2764
xm.astype(np.uint8)
2765
)
2766
return othertypes, uint8data
2767
2768
def test_inplace_addition_scalar(self):
2769
# Test of inplace additions
2770
x, y, xm = self._create_intdata()
2771
xm[2] = masked
2772
x += 1
2773
assert_equal(x, y + 1)
2774
xm += 1
2775
assert_equal(xm, y + 1)
2776
2777
x, _, xm = self._create_floatdata()
2778
id1 = x.data.ctypes.data
2779
x += 1.
2780
assert_(id1 == x.data.ctypes.data)
2781
assert_equal(x, y + 1.)
2782
2783
def test_inplace_addition_array(self):
2784
# Test of inplace additions
2785
x, y, xm = self._create_intdata()
2786
m = xm.mask
2787
a = arange(10, dtype=np.int16)
2788
a[-1] = masked
2789
x += a
2790
xm += a
2791
assert_equal(x, y + a)
2792
assert_equal(xm, y + a)
2793
assert_equal(xm.mask, mask_or(m, a.mask))
2794
2795
def test_inplace_subtraction_scalar(self):
2796
# Test of inplace subtractions
2797
x, y, xm = self._create_intdata()
2798
x -= 1
2799
assert_equal(x, y - 1)
2800
xm -= 1
2801
assert_equal(xm, y - 1)
2802
2803
def test_inplace_subtraction_array(self):
2804
# Test of inplace subtractions
2805
x, y, xm = self._create_floatdata()
2806
m = xm.mask
2807
a = arange(10, dtype=float)
2808
a[-1] = masked
2809
x -= a
2810
xm -= a
2811
assert_equal(x, y - a)
2812
assert_equal(xm, y - a)
2813
assert_equal(xm.mask, mask_or(m, a.mask))
2814
2815
def test_inplace_multiplication_scalar(self):
2816
# Test of inplace multiplication
2817
x, y, xm = self._create_floatdata()
2818
x *= 2.0
2819
assert_equal(x, y * 2)
2820
xm *= 2.0
2821
assert_equal(xm, y * 2)
2822
2823
def test_inplace_multiplication_array(self):
2824
# Test of inplace multiplication
2825
x, y, xm = self._create_floatdata()
2826
m = xm.mask
2827
a = arange(10, dtype=float)
2828
a[-1] = masked
2829
x *= a
2830
xm *= a
2831
assert_equal(x, y * a)
2832
assert_equal(xm, y * a)
2833
assert_equal(xm.mask, mask_or(m, a.mask))
2834
2835
def test_inplace_division_scalar_int(self):
2836
# Test of inplace division
2837
x, y, xm = self._create_intdata()
2838
x = arange(10) * 2
2839
xm = arange(10) * 2
2840
xm[2] = masked
2841
x //= 2
2842
assert_equal(x, y)
2843
xm //= 2
2844
assert_equal(xm, y)
2845
2846
def test_inplace_division_scalar_float(self):
2847
# Test of inplace division
2848
x, y, xm = self._create_floatdata()
2849
x /= 2.0
2850
assert_equal(x, y / 2.0)
2851
xm /= arange(10)
2852
assert_equal(xm, ones((10,)))
2853
2854
def test_inplace_division_array_float(self):
2855
# Test of inplace division
2856
x, y, xm = self._create_floatdata()
2857
m = xm.mask
2858
a = arange(10, dtype=float)
2859
a[-1] = masked
2860
x /= a
2861
xm /= a
2862
assert_equal(x, y / a)
2863
assert_equal(xm, y / a)
2864
assert_equal(xm.mask, mask_or(mask_or(m, a.mask), (a == 0)))
2865
2866
def test_inplace_division_misc(self):
2867
2868
x = [1., 1., 1., -2., pi / 2., 4., 5., -10., 10., 1., 2., 3.]
2869
y = [5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.]
2870
m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
2871
m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
2872
xm = masked_array(x, mask=m1)
2873
ym = masked_array(y, mask=m2)
2874
2875
z = xm / ym
2876
assert_equal(z._mask, [1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1])
2877
assert_equal(z._data,
2878
[1., 1., 1., -1., -pi / 2., 4., 5., 1., 1., 1., 2., 3.])
2879
2880
xm = xm.copy()
2881
xm /= ym
2882
assert_equal(xm._mask, [1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1])
2883
assert_equal(z._data,
2884
[1., 1., 1., -1., -pi / 2., 4., 5., 1., 1., 1., 2., 3.])
2885
2886
def test_datafriendly_add(self):
2887
# Test keeping data w/ (inplace) addition
2888
x = array([1, 2, 3], mask=[0, 0, 1])
2889
# Test add w/ scalar
2890
xx = x + 1
2891
assert_equal(xx.data, [2, 3, 3])
2892
assert_equal(xx.mask, [0, 0, 1])
2893
# Test iadd w/ scalar
2894
x += 1
2895
assert_equal(x.data, [2, 3, 3])
2896
assert_equal(x.mask, [0, 0, 1])
2897
# Test add w/ array
2898
x = array([1, 2, 3], mask=[0, 0, 1])
2899
xx = x + array([1, 2, 3], mask=[1, 0, 0])
2900
assert_equal(xx.data, [1, 4, 3])
2901
assert_equal(xx.mask, [1, 0, 1])
2902
# Test iadd w/ array
2903
x = array([1, 2, 3], mask=[0, 0, 1])
2904
x += array([1, 2, 3], mask=[1, 0, 0])
2905
assert_equal(x.data, [1, 4, 3])
2906
assert_equal(x.mask, [1, 0, 1])
2907
2908
def test_datafriendly_sub(self):
2909
# Test keeping data w/ (inplace) subtraction
2910
# Test sub w/ scalar
2911
x = array([1, 2, 3], mask=[0, 0, 1])
2912
xx = x - 1
2913
assert_equal(xx.data, [0, 1, 3])
2914
assert_equal(xx.mask, [0, 0, 1])
2915
# Test isub w/ scalar
2916
x = array([1, 2, 3], mask=[0, 0, 1])
2917
x -= 1
2918
assert_equal(x.data, [0, 1, 3])
2919
assert_equal(x.mask, [0, 0, 1])
2920
# Test sub w/ array
2921
x = array([1, 2, 3], mask=[0, 0, 1])
2922
xx = x - array([1, 2, 3], mask=[1, 0, 0])
2923
assert_equal(xx.data, [1, 0, 3])
2924
assert_equal(xx.mask, [1, 0, 1])
2925
# Test isub w/ array
2926
x = array([1, 2, 3], mask=[0, 0, 1])
2927
x -= array([1, 2, 3], mask=[1, 0, 0])
2928
assert_equal(x.data, [1, 0, 3])
2929
assert_equal(x.mask, [1, 0, 1])
2930
2931
def test_datafriendly_mul(self):
2932
# Test keeping data w/ (inplace) multiplication
2933
# Test mul w/ scalar
2934
x = array([1, 2, 3], mask=[0, 0, 1])
2935
xx = x * 2
2936
assert_equal(xx.data, [2, 4, 3])
2937
assert_equal(xx.mask, [0, 0, 1])
2938
# Test imul w/ scalar
2939
x = array([1, 2, 3], mask=[0, 0, 1])
2940
x *= 2
2941
assert_equal(x.data, [2, 4, 3])
2942
assert_equal(x.mask, [0, 0, 1])
2943
# Test mul w/ array
2944
x = array([1, 2, 3], mask=[0, 0, 1])
2945
xx = x * array([10, 20, 30], mask=[1, 0, 0])
2946
assert_equal(xx.data, [1, 40, 3])
2947
assert_equal(xx.mask, [1, 0, 1])
2948
# Test imul w/ array
2949
x = array([1, 2, 3], mask=[0, 0, 1])
2950
x *= array([10, 20, 30], mask=[1, 0, 0])
2951
assert_equal(x.data, [1, 40, 3])
2952
assert_equal(x.mask, [1, 0, 1])
2953
2954
def test_datafriendly_div(self):
2955
# Test keeping data w/ (inplace) division
2956
# Test div on scalar
2957
x = array([1, 2, 3], mask=[0, 0, 1])
2958
xx = x / 2.
2959
assert_equal(xx.data, [1 / 2., 2 / 2., 3])
2960
assert_equal(xx.mask, [0, 0, 1])
2961
# Test idiv on scalar
2962
x = array([1., 2., 3.], mask=[0, 0, 1])
2963
x /= 2.
2964
assert_equal(x.data, [1 / 2., 2 / 2., 3])
2965
assert_equal(x.mask, [0, 0, 1])
2966
# Test div on array
2967
x = array([1., 2., 3.], mask=[0, 0, 1])
2968
xx = x / array([10., 20., 30.], mask=[1, 0, 0])
2969
assert_equal(xx.data, [1., 2. / 20., 3.])
2970
assert_equal(xx.mask, [1, 0, 1])
2971
# Test idiv on array
2972
x = array([1., 2., 3.], mask=[0, 0, 1])
2973
x /= array([10., 20., 30.], mask=[1, 0, 0])
2974
assert_equal(x.data, [1., 2 / 20., 3.])
2975
assert_equal(x.mask, [1, 0, 1])
2976
2977
def test_datafriendly_pow(self):
2978
# Test keeping data w/ (inplace) power
2979
# Test pow on scalar
2980
x = array([1., 2., 3.], mask=[0, 0, 1])
2981
xx = x ** 2.5
2982
assert_equal(xx.data, [1., 2. ** 2.5, 3.])
2983
assert_equal(xx.mask, [0, 0, 1])
2984
# Test ipow on scalar
2985
x **= 2.5
2986
assert_equal(x.data, [1., 2. ** 2.5, 3])
2987
assert_equal(x.mask, [0, 0, 1])
2988
2989
def test_datafriendly_add_arrays(self):
2990
a = array([[1, 1], [3, 3]])
2991
b = array([1, 1], mask=[0, 0])
2992
a += b
2993
assert_equal(a, [[2, 2], [4, 4]])
2994
if a.mask is not nomask:
2995
assert_equal(a.mask, [[0, 0], [0, 0]])
2996
2997
a = array([[1, 1], [3, 3]])
2998
b = array([1, 1], mask=[0, 1])
2999
a += b
3000
assert_equal(a, [[2, 2], [4, 4]])
3001
assert_equal(a.mask, [[0, 1], [0, 1]])
3002
3003
def test_datafriendly_sub_arrays(self):
3004
a = array([[1, 1], [3, 3]])
3005
b = array([1, 1], mask=[0, 0])
3006
a -= b
3007
assert_equal(a, [[0, 0], [2, 2]])
3008
if a.mask is not nomask:
3009
assert_equal(a.mask, [[0, 0], [0, 0]])
3010
3011
a = array([[1, 1], [3, 3]])
3012
b = array([1, 1], mask=[0, 1])
3013
a -= b
3014
assert_equal(a, [[0, 0], [2, 2]])
3015
assert_equal(a.mask, [[0, 1], [0, 1]])
3016
3017
def test_datafriendly_mul_arrays(self):
3018
a = array([[1, 1], [3, 3]])
3019
b = array([1, 1], mask=[0, 0])
3020
a *= b
3021
assert_equal(a, [[1, 1], [3, 3]])
3022
if a.mask is not nomask:
3023
assert_equal(a.mask, [[0, 0], [0, 0]])
3024
3025
a = array([[1, 1], [3, 3]])
3026
b = array([1, 1], mask=[0, 1])
3027
a *= b
3028
assert_equal(a, [[1, 1], [3, 3]])
3029
assert_equal(a.mask, [[0, 1], [0, 1]])
3030
3031
def test_inplace_addition_scalar_type(self):
3032
# Test of inplace additions
3033
othertypes, uint8data = self._create_otherdata()
3034
for t in othertypes:
3035
with warnings.catch_warnings():
3036
warnings.filterwarnings("error")
3037
x, y, xm = (_.astype(t) for _ in uint8data)
3038
xm[2] = masked
3039
x += t(1)
3040
assert_equal(x, y + t(1))
3041
xm += t(1)
3042
assert_equal(xm, y + t(1))
3043
3044
def test_inplace_addition_array_type(self):
3045
# Test of inplace additions
3046
othertypes, uint8data = self._create_otherdata()
3047
for t in othertypes:
3048
with warnings.catch_warnings():
3049
warnings.filterwarnings("error")
3050
x, y, xm = (_.astype(t) for _ in uint8data)
3051
m = xm.mask
3052
a = arange(10, dtype=t)
3053
a[-1] = masked
3054
x += a
3055
xm += a
3056
assert_equal(x, y + a)
3057
assert_equal(xm, y + a)
3058
assert_equal(xm.mask, mask_or(m, a.mask))
3059
3060
def test_inplace_subtraction_scalar_type(self):
3061
# Test of inplace subtractions
3062
othertypes, uint8data = self._create_otherdata()
3063
for t in othertypes:
3064
with warnings.catch_warnings():
3065
warnings.filterwarnings("error")
3066
x, y, xm = (_.astype(t) for _ in uint8data)
3067
x -= t(1)
3068
assert_equal(x, y - t(1))
3069
xm -= t(1)
3070
assert_equal(xm, y - t(1))
3071
3072
def test_inplace_subtraction_array_type(self):
3073
# Test of inplace subtractions
3074
othertypes, uint8data = self._create_otherdata()
3075
for t in othertypes:
3076
with warnings.catch_warnings():
3077
warnings.filterwarnings("error")
3078
x, y, xm = (_.astype(t) for _ in uint8data)
3079
m = xm.mask
3080
a = arange(10, dtype=t)
3081
a[-1] = masked
3082
x -= a
3083
xm -= a
3084
assert_equal(x, y - a)
3085
assert_equal(xm, y - a)
3086
assert_equal(xm.mask, mask_or(m, a.mask))
3087
3088
def test_inplace_multiplication_scalar_type(self):
3089
# Test of inplace multiplication
3090
othertypes, uint8data = self._create_otherdata()
3091
for t in othertypes:
3092
with warnings.catch_warnings():
3093
warnings.filterwarnings("error")
3094
x, y, xm = (_.astype(t) for _ in uint8data)
3095
x *= t(2)
3096
assert_equal(x, y * t(2))
3097
xm *= t(2)
3098
assert_equal(xm, y * t(2))
3099
3100
def test_inplace_multiplication_array_type(self):
3101
# Test of inplace multiplication
3102
othertypes, uint8data = self._create_otherdata()
3103
for t in othertypes:
3104
with warnings.catch_warnings():
3105
warnings.filterwarnings("error")
3106
x, y, xm = (_.astype(t) for _ in uint8data)
3107
m = xm.mask
3108
a = arange(10, dtype=t)
3109
a[-1] = masked
3110
x *= a
3111
xm *= a
3112
assert_equal(x, y * a)
3113
assert_equal(xm, y * a)
3114
assert_equal(xm.mask, mask_or(m, a.mask))
3115
3116
def test_inplace_floor_division_scalar_type(self):
3117
# Test of inplace division
3118
# Check for TypeError in case of unsupported types
3119
othertypes, uint8data = self._create_otherdata()
3120
unsupported = {np.dtype(t).type for t in np.typecodes["Complex"]}
3121
for t in othertypes:
3122
with warnings.catch_warnings():
3123
warnings.filterwarnings("error")
3124
x, y, xm = (_.astype(t) for _ in uint8data)
3125
x = arange(10, dtype=t) * t(2)
3126
xm = arange(10, dtype=t) * t(2)
3127
xm[2] = masked
3128
try:
3129
x //= t(2)
3130
xm //= t(2)
3131
assert_equal(x, y)
3132
assert_equal(xm, y)
3133
except TypeError:
3134
msg = f"Supported type {t} throwing TypeError"
3135
assert t in unsupported, msg
3136
3137
def test_inplace_floor_division_array_type(self):
3138
# Test of inplace division
3139
# Check for TypeError in case of unsupported types
3140
othertypes, uint8data = self._create_otherdata()
3141
unsupported = {np.dtype(t).type for t in np.typecodes["Complex"]}
3142
for t in othertypes:
3143
with warnings.catch_warnings():
3144
warnings.filterwarnings("error")
3145
x, y, xm = (_.astype(t) for _ in uint8data)
3146
m = xm.mask
3147
a = arange(10, dtype=t)
3148
a[-1] = masked
3149
try:
3150
x //= a
3151
xm //= a
3152
assert_equal(x, y // a)
3153
assert_equal(xm, y // a)
3154
assert_equal(
3155
xm.mask,
3156
mask_or(mask_or(m, a.mask), (a == t(0)))
3157
)
3158
except TypeError:
3159
msg = f"Supported type {t} throwing TypeError"
3160
assert t in unsupported, msg
3161
3162
def test_inplace_division_scalar_type(self):
3163
# Test of inplace division
3164
othertypes, uint8data = self._create_otherdata()
3165
with warnings.catch_warnings():
3166
warnings.simplefilter('error', DeprecationWarning)
3167
for t in othertypes:
3168
x, y, xm = (_.astype(t) for _ in uint8data)
3169
x = arange(10, dtype=t) * t(2)
3170
xm = arange(10, dtype=t) * t(2)
3171
xm[2] = masked
3172
nwarns = 0
3173
3174
# May get a DeprecationWarning or a TypeError.
3175
#
3176
# This is a consequence of the fact that this is true divide
3177
# and will require casting to float for calculation and
3178
# casting back to the original type. This will only be raised
3179
# with integers. Whether it is an error or warning is only
3180
# dependent on how stringent the casting rules are.
3181
#
3182
# Will handle the same way.
3183
try:
3184
x /= t(2)
3185
assert_equal(x, y)
3186
except (DeprecationWarning, TypeError):
3187
nwarns += 1
3188
try:
3189
xm /= t(2)
3190
assert_equal(xm, y)
3191
except (DeprecationWarning, TypeError):
3192
nwarns += 1
3193
3194
if issubclass(t, np.integer):
3195
assert_equal(nwarns, 2, f'Failed on type={t}.')
3196
else:
3197
assert_equal(nwarns, 0, f'Failed on type={t}.')
3198
3199
def test_inplace_division_array_type(self):
3200
# Test of inplace division
3201
othertypes, uint8data = self._create_otherdata()
3202
with warnings.catch_warnings():
3203
warnings.simplefilter('error', DeprecationWarning)
3204
for t in othertypes:
3205
x, y, xm = (_.astype(t) for _ in uint8data)
3206
m = xm.mask
3207
a = arange(10, dtype=t)
3208
a[-1] = masked
3209
nwarns = 0
3210
3211
# May get a DeprecationWarning or a TypeError.
3212
#
3213
# This is a consequence of the fact that this is true divide
3214
# and will require casting to float for calculation and
3215
# casting back to the original type. This will only be raised
3216
# with integers. Whether it is an error or warning is only
3217
# dependent on how stringent the casting rules are.
3218
#
3219
# Will handle the same way.
3220
try:
3221
x /= a
3222
assert_equal(x, y / a)
3223
except (DeprecationWarning, TypeError):
3224
nwarns += 1
3225
try:
3226
xm /= a
3227
assert_equal(xm, y / a)
3228
assert_equal(
3229
xm.mask,
3230
mask_or(mask_or(m, a.mask), (a == t(0)))
3231
)
3232
except (DeprecationWarning, TypeError):
3233
nwarns += 1
3234
3235
if issubclass(t, np.integer):
3236
assert_equal(nwarns, 2, f'Failed on type={t}.')
3237
else:
3238
assert_equal(nwarns, 0, f'Failed on type={t}.')
3239
3240
def test_inplace_pow_type(self):
3241
# Test keeping data w/ (inplace) power
3242
othertypes = self._create_otherdata()[0]
3243
for t in othertypes:
3244
with warnings.catch_warnings():
3245
warnings.filterwarnings("error")
3246
# Test pow on scalar
3247
x = array([1, 2, 3], mask=[0, 0, 1], dtype=t)
3248
xx = x ** t(2)
3249
xx_r = array([1, 2 ** 2, 3], mask=[0, 0, 1], dtype=t)
3250
assert_equal(xx.data, xx_r.data)
3251
assert_equal(xx.mask, xx_r.mask)
3252
# Test ipow on scalar
3253
x **= t(2)
3254
assert_equal(x.data, xx_r.data)
3255
assert_equal(x.mask, xx_r.mask)
3256
3257
3258
class TestMaskedArrayMethods:
3259
# Test class for miscellaneous MaskedArrays methods.
3260
def _create_data(self):
3261
# Base data definition.
3262
x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928,
3263
8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
3264
3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
3265
6.04, 9.63, 7.712, 3.382, 4.489, 6.479,
3266
7.189, 9.645, 5.395, 4.961, 9.894, 2.893,
3267
7.357, 9.828, 6.272, 3.758, 6.693, 0.993])
3268
X = x.reshape(6, 6)
3269
XX = x.reshape(3, 2, 2, 3)
3270
3271
m = np.array([0, 1, 0, 1, 0, 0,
3272
1, 0, 1, 1, 0, 1,
3273
0, 0, 0, 1, 0, 1,
3274
0, 0, 0, 1, 1, 1,
3275
1, 0, 0, 1, 0, 0,
3276
0, 0, 1, 0, 1, 0])
3277
mx = array(data=x, mask=m)
3278
mX = array(data=X, mask=m.reshape(X.shape))
3279
mXX = array(data=XX, mask=m.reshape(XX.shape))
3280
3281
m2 = np.array([1, 1, 0, 1, 0, 0,
3282
1, 1, 1, 1, 0, 1,
3283
0, 0, 1, 1, 0, 1,
3284
0, 0, 0, 1, 1, 1,
3285
1, 0, 0, 1, 1, 0,
3286
0, 0, 1, 0, 1, 1])
3287
m2x = array(data=x, mask=m2)
3288
m2X = array(data=X, mask=m2.reshape(X.shape))
3289
m2XX = array(data=XX, mask=m2.reshape(XX.shape))
3290
return x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX
3291
3292
def test_generic_methods(self):
3293
# Tests some MaskedArray methods.
3294
a = array([1, 3, 2])
3295
assert_equal(a.any(), a._data.any())
3296
assert_equal(a.all(), a._data.all())
3297
assert_equal(a.argmax(), a._data.argmax())
3298
assert_equal(a.argmin(), a._data.argmin())
3299
assert_equal(a.choose(0, 1, 2, 3, 4), a._data.choose(0, 1, 2, 3, 4))
3300
assert_equal(a.compress([1, 0, 1]), a._data.compress([1, 0, 1]))
3301
assert_equal(a.conj(), a._data.conj())
3302
assert_equal(a.conjugate(), a._data.conjugate())
3303
3304
m = array([[1, 2], [3, 4]])
3305
assert_equal(m.diagonal(), m._data.diagonal())
3306
assert_equal(a.sum(), a._data.sum())
3307
assert_equal(a.take([1, 2]), a._data.take([1, 2]))
3308
assert_equal(m.transpose(), m._data.transpose())
3309
3310
def test_allclose(self):
3311
# Tests allclose on arrays
3312
a = np.random.rand(10)
3313
b = a + np.random.rand(10) * 1e-8
3314
assert_(allclose(a, b))
3315
# Test allclose w/ infs
3316
a[0] = np.inf
3317
assert_(not allclose(a, b))
3318
b[0] = np.inf
3319
assert_(allclose(a, b))
3320
# Test allclose w/ masked
3321
a = masked_array(a)
3322
a[-1] = masked
3323
assert_(allclose(a, b, masked_equal=True))
3324
assert_(not allclose(a, b, masked_equal=False))
3325
# Test comparison w/ scalar
3326
a *= 1e-8
3327
a[0] = 0
3328
assert_(allclose(a, 0, masked_equal=True))
3329
3330
# Test that the function works for MIN_INT integer typed arrays
3331
a = masked_array([np.iinfo(np.int_).min], dtype=np.int_)
3332
assert_(allclose(a, a))
3333
3334
def test_allclose_timedelta(self):
3335
# Allclose currently works for timedelta64 as long as `atol` is
3336
# an integer or also a timedelta64
3337
a = np.array([[1, 2, 3, 4]], dtype="m8[ns]")
3338
assert allclose(a, a, atol=0)
3339
assert allclose(a, a, atol=np.timedelta64(1, "ns"))
3340
3341
def test_allany(self):
3342
# Checks the any/all methods/functions.
3343
x = np.array([[0.13, 0.26, 0.90],
3344
[0.28, 0.33, 0.63],
3345
[0.31, 0.87, 0.70]])
3346
m = np.array([[True, False, False],
3347
[False, False, False],
3348
[True, True, False]], dtype=np.bool)
3349
mx = masked_array(x, mask=m)
3350
mxbig = (mx > 0.5)
3351
mxsmall = (mx < 0.5)
3352
3353
assert_(not mxbig.all())
3354
assert_(mxbig.any())
3355
assert_equal(mxbig.all(0), [False, False, True])
3356
assert_equal(mxbig.all(1), [False, False, True])
3357
assert_equal(mxbig.any(0), [False, False, True])
3358
assert_equal(mxbig.any(1), [True, True, True])
3359
3360
assert_(not mxsmall.all())
3361
assert_(mxsmall.any())
3362
assert_equal(mxsmall.all(0), [True, True, False])
3363
assert_equal(mxsmall.all(1), [False, False, False])
3364
assert_equal(mxsmall.any(0), [True, True, False])
3365
assert_equal(mxsmall.any(1), [True, True, False])
3366
3367
def test_allany_oddities(self):
3368
# Some fun with all and any
3369
store = empty((), dtype=bool)
3370
full = array([1, 2, 3], mask=True)
3371
3372
assert_(full.all() is masked)
3373
full.all(out=store)
3374
assert_(store)
3375
assert_(store._mask, True)
3376
assert_(store is not masked)
3377
3378
store = empty((), dtype=bool)
3379
assert_(full.any() is masked)
3380
full.any(out=store)
3381
assert_(not store)
3382
assert_(store._mask, True)
3383
assert_(store is not masked)
3384
3385
def test_argmax_argmin(self):
3386
# Tests argmin & argmax on MaskedArrays.
3387
_, _, _, _, mx, mX, _, m2x, m2X, _ = self._create_data()
3388
3389
assert_equal(mx.argmin(), 35)
3390
assert_equal(mX.argmin(), 35)
3391
assert_equal(m2x.argmin(), 4)
3392
assert_equal(m2X.argmin(), 4)
3393
assert_equal(mx.argmax(), 28)
3394
assert_equal(mX.argmax(), 28)
3395
assert_equal(m2x.argmax(), 31)
3396
assert_equal(m2X.argmax(), 31)
3397
3398
assert_equal(mX.argmin(0), [2, 2, 2, 5, 0, 5])
3399
assert_equal(m2X.argmin(0), [2, 2, 4, 5, 0, 4])
3400
assert_equal(mX.argmax(0), [0, 5, 0, 5, 4, 0])
3401
assert_equal(m2X.argmax(0), [5, 5, 0, 5, 1, 0])
3402
3403
assert_equal(mX.argmin(1), [4, 1, 0, 0, 5, 5, ])
3404
assert_equal(m2X.argmin(1), [4, 4, 0, 0, 5, 3])
3405
assert_equal(mX.argmax(1), [2, 4, 1, 1, 4, 1])
3406
assert_equal(m2X.argmax(1), [2, 4, 1, 1, 1, 1])
3407
3408
def test_clip(self):
3409
# Tests clip on MaskedArrays.
3410
x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928,
3411
8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
3412
3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
3413
6.04, 9.63, 7.712, 3.382, 4.489, 6.479,
3414
7.189, 9.645, 5.395, 4.961, 9.894, 2.893,
3415
7.357, 9.828, 6.272, 3.758, 6.693, 0.993])
3416
m = np.array([0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1,
3417
0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1,
3418
1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0])
3419
mx = array(x, mask=m)
3420
clipped = mx.clip(2, 8)
3421
assert_equal(clipped.mask, mx.mask)
3422
assert_equal(clipped._data, x.clip(2, 8))
3423
assert_equal(clipped._data, mx._data.clip(2, 8))
3424
3425
def test_clip_out(self):
3426
# gh-14140
3427
a = np.arange(10)
3428
m = np.ma.MaskedArray(a, mask=[0, 1] * 5)
3429
m.clip(0, 5, out=m)
3430
assert_equal(m.mask, [0, 1] * 5)
3431
3432
def test_compress(self):
3433
# test compress
3434
a = masked_array([1., 2., 3., 4., 5.], fill_value=9999)
3435
condition = (a > 1.5) & (a < 3.5)
3436
assert_equal(a.compress(condition), [2., 3.])
3437
3438
a[[2, 3]] = masked
3439
b = a.compress(condition)
3440
assert_equal(b._data, [2., 3.])
3441
assert_equal(b._mask, [0, 1])
3442
assert_equal(b.fill_value, 9999)
3443
assert_equal(b, a[condition])
3444
3445
condition = (a < 4.)
3446
b = a.compress(condition)
3447
assert_equal(b._data, [1., 2., 3.])
3448
assert_equal(b._mask, [0, 0, 1])
3449
assert_equal(b.fill_value, 9999)
3450
assert_equal(b, a[condition])
3451
3452
a = masked_array([[10, 20, 30], [40, 50, 60]],
3453
mask=[[0, 0, 1], [1, 0, 0]])
3454
b = a.compress(a.ravel() >= 22)
3455
assert_equal(b._data, [30, 40, 50, 60])
3456
assert_equal(b._mask, [1, 1, 0, 0])
3457
3458
x = np.array([3, 1, 2])
3459
b = a.compress(x >= 2, axis=1)
3460
assert_equal(b._data, [[10, 30], [40, 60]])
3461
assert_equal(b._mask, [[0, 1], [1, 0]])
3462
3463
def test_compressed(self):
3464
# Tests compressed
3465
a = array([1, 2, 3, 4], mask=[0, 0, 0, 0])
3466
b = a.compressed()
3467
assert_equal(b, a)
3468
a[0] = masked
3469
b = a.compressed()
3470
assert_equal(b, [2, 3, 4])
3471
3472
def test_empty(self):
3473
# Tests empty/like
3474
datatype = [('a', int), ('b', float), ('c', '|S8')]
3475
a = masked_array([(1, 1.1, '1.1'), (2, 2.2, '2.2'), (3, 3.3, '3.3')],
3476
dtype=datatype)
3477
assert_equal(len(a.fill_value.item()), len(datatype))
3478
3479
b = empty_like(a)
3480
assert_equal(b.shape, a.shape)
3481
assert_equal(b.fill_value, a.fill_value)
3482
3483
b = empty(len(a), dtype=datatype)
3484
assert_equal(b.shape, a.shape)
3485
assert_equal(b.fill_value, a.fill_value)
3486
3487
# check empty_like mask handling
3488
a = masked_array([1, 2, 3], mask=[False, True, False])
3489
b = empty_like(a)
3490
assert_(not np.may_share_memory(a.mask, b.mask))
3491
b = a.view(masked_array)
3492
assert_(np.may_share_memory(a.mask, b.mask))
3493
3494
def test_zeros(self):
3495
# Tests zeros/like
3496
datatype = [('a', int), ('b', float), ('c', '|S8')]
3497
a = masked_array([(1, 1.1, '1.1'), (2, 2.2, '2.2'), (3, 3.3, '3.3')],
3498
dtype=datatype)
3499
assert_equal(len(a.fill_value.item()), len(datatype))
3500
3501
b = zeros(len(a), dtype=datatype)
3502
assert_equal(b.shape, a.shape)
3503
assert_equal(b.fill_value, a.fill_value)
3504
3505
b = zeros_like(a)
3506
assert_equal(b.shape, a.shape)
3507
assert_equal(b.fill_value, a.fill_value)
3508
3509
# check zeros_like mask handling
3510
a = masked_array([1, 2, 3], mask=[False, True, False])
3511
b = zeros_like(a)
3512
assert_(not np.may_share_memory(a.mask, b.mask))
3513
b = a.view()
3514
assert_(np.may_share_memory(a.mask, b.mask))
3515
3516
def test_ones(self):
3517
# Tests ones/like
3518
datatype = [('a', int), ('b', float), ('c', '|S8')]
3519
a = masked_array([(1, 1.1, '1.1'), (2, 2.2, '2.2'), (3, 3.3, '3.3')],
3520
dtype=datatype)
3521
assert_equal(len(a.fill_value.item()), len(datatype))
3522
3523
b = ones(len(a), dtype=datatype)
3524
assert_equal(b.shape, a.shape)
3525
assert_equal(b.fill_value, a.fill_value)
3526
3527
b = ones_like(a)
3528
assert_equal(b.shape, a.shape)
3529
assert_equal(b.fill_value, a.fill_value)
3530
3531
# check ones_like mask handling
3532
a = masked_array([1, 2, 3], mask=[False, True, False])
3533
b = ones_like(a)
3534
assert_(not np.may_share_memory(a.mask, b.mask))
3535
b = a.view()
3536
assert_(np.may_share_memory(a.mask, b.mask))
3537
3538
@pytest.mark.filterwarnings(WARNING_MARK_SPEC)
3539
def test_put(self):
3540
# Tests put.
3541
d = arange(5)
3542
n = [0, 0, 0, 1, 1]
3543
m = make_mask(n)
3544
x = array(d, mask=m)
3545
assert_(x[3] is masked)
3546
assert_(x[4] is masked)
3547
x[[1, 4]] = [10, 40]
3548
assert_(x[3] is masked)
3549
assert_(x[4] is not masked)
3550
assert_equal(x, [0, 10, 2, -1, 40])
3551
3552
x = masked_array(arange(10), mask=[1, 0, 0, 0, 0] * 2)
3553
i = [0, 2, 4, 6]
3554
x.put(i, [6, 4, 2, 0])
3555
assert_equal(x, asarray([6, 1, 4, 3, 2, 5, 0, 7, 8, 9, ]))
3556
assert_equal(x.mask, [0, 0, 0, 0, 0, 1, 0, 0, 0, 0])
3557
x.put(i, masked_array([0, 2, 4, 6], [1, 0, 1, 0]))
3558
assert_array_equal(x, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ])
3559
assert_equal(x.mask, [1, 0, 0, 0, 1, 1, 0, 0, 0, 0])
3560
3561
x = masked_array(arange(10), mask=[1, 0, 0, 0, 0] * 2)
3562
put(x, i, [6, 4, 2, 0])
3563
assert_equal(x, asarray([6, 1, 4, 3, 2, 5, 0, 7, 8, 9, ]))
3564
assert_equal(x.mask, [0, 0, 0, 0, 0, 1, 0, 0, 0, 0])
3565
put(x, i, masked_array([0, 2, 4, 6], [1, 0, 1, 0]))
3566
assert_array_equal(x, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ])
3567
assert_equal(x.mask, [1, 0, 0, 0, 1, 1, 0, 0, 0, 0])
3568
3569
def test_put_nomask(self):
3570
# GitHub issue 6425
3571
x = zeros(10)
3572
z = array([3., -1.], mask=[False, True])
3573
3574
x.put([1, 2], z)
3575
assert_(x[0] is not masked)
3576
assert_equal(x[0], 0)
3577
assert_(x[1] is not masked)
3578
assert_equal(x[1], 3)
3579
assert_(x[2] is masked)
3580
assert_(x[3] is not masked)
3581
assert_equal(x[3], 0)
3582
3583
def test_put_hardmask(self):
3584
# Tests put on hardmask
3585
d = arange(5)
3586
n = [0, 0, 0, 1, 1]
3587
m = make_mask(n)
3588
xh = array(d + 1, mask=m, hard_mask=True, copy=True)
3589
xh.put([4, 2, 0, 1, 3], [1, 2, 3, 4, 5])
3590
assert_equal(xh._data, [3, 4, 2, 4, 5])
3591
3592
def test_putmask(self):
3593
x = arange(6) + 1
3594
mx = array(x, mask=[0, 0, 0, 1, 1, 1])
3595
mask = [0, 0, 1, 0, 0, 1]
3596
# w/o mask, w/o masked values
3597
xx = x.copy()
3598
putmask(xx, mask, 99)
3599
assert_equal(xx, [1, 2, 99, 4, 5, 99])
3600
# w/ mask, w/o masked values
3601
mxx = mx.copy()
3602
putmask(mxx, mask, 99)
3603
assert_equal(mxx._data, [1, 2, 99, 4, 5, 99])
3604
assert_equal(mxx._mask, [0, 0, 0, 1, 1, 0])
3605
# w/o mask, w/ masked values
3606
values = array([10, 20, 30, 40, 50, 60], mask=[1, 1, 1, 0, 0, 0])
3607
xx = x.copy()
3608
putmask(xx, mask, values)
3609
assert_equal(xx._data, [1, 2, 30, 4, 5, 60])
3610
assert_equal(xx._mask, [0, 0, 1, 0, 0, 0])
3611
# w/ mask, w/ masked values
3612
mxx = mx.copy()
3613
putmask(mxx, mask, values)
3614
assert_equal(mxx._data, [1, 2, 30, 4, 5, 60])
3615
assert_equal(mxx._mask, [0, 0, 1, 1, 1, 0])
3616
# w/ mask, w/ masked values + hardmask
3617
mxx = mx.copy()
3618
mxx.harden_mask()
3619
putmask(mxx, mask, values)
3620
assert_equal(mxx, [1, 2, 30, 4, 5, 60])
3621
3622
def test_ravel(self):
3623
# Tests ravel
3624
a = array([[1, 2, 3, 4, 5]], mask=[[0, 1, 0, 0, 0]])
3625
aravel = a.ravel()
3626
assert_equal(aravel._mask.shape, aravel.shape)
3627
a = array([0, 0], mask=[1, 1])
3628
aravel = a.ravel()
3629
assert_equal(aravel._mask.shape, a.shape)
3630
# Checks that small_mask is preserved
3631
a = array([1, 2, 3, 4], mask=[0, 0, 0, 0], shrink=False)
3632
assert_equal(a.ravel()._mask, [0, 0, 0, 0])
3633
# Test that the fill_value is preserved
3634
a.fill_value = -99
3635
a.shape = (2, 2)
3636
ar = a.ravel()
3637
assert_equal(ar._mask, [0, 0, 0, 0])
3638
assert_equal(ar._data, [1, 2, 3, 4])
3639
assert_equal(ar.fill_value, -99)
3640
# Test index ordering
3641
assert_equal(a.ravel(order='C'), [1, 2, 3, 4])
3642
assert_equal(a.ravel(order='F'), [1, 3, 2, 4])
3643
3644
@pytest.mark.parametrize("order", "AKCF")
3645
@pytest.mark.parametrize("data_order", "CF")
3646
def test_ravel_order(self, order, data_order):
3647
# Ravelling must ravel mask and data in the same order always to avoid
3648
# misaligning the two in the ravel result.
3649
arr = np.ones((5, 10), order=data_order)
3650
arr[0, :] = 0
3651
mask = np.ones((10, 5), dtype=bool, order=data_order).T
3652
mask[0, :] = False
3653
x = array(arr, mask=mask)
3654
assert x._data.flags.fnc != x._mask.flags.fnc
3655
assert (x.filled(0) == 0).all()
3656
raveled = x.ravel(order)
3657
assert (raveled.filled(0) == 0).all()
3658
3659
# NOTE: Can be wrong if arr order is neither C nor F and `order="K"`
3660
assert_array_equal(arr.ravel(order), x.ravel(order)._data)
3661
3662
def test_reshape(self):
3663
# Tests reshape
3664
x = arange(4)
3665
x[0] = masked
3666
y = x.reshape(2, 2)
3667
assert_equal(y.shape, (2, 2,))
3668
assert_equal(y._mask.shape, (2, 2,))
3669
assert_equal(x.shape, (4,))
3670
assert_equal(x._mask.shape, (4,))
3671
3672
def test_sort(self):
3673
# Test sort
3674
x = array([1, 4, 2, 3], mask=[0, 1, 0, 0], dtype=np.uint8)
3675
3676
sortedx = sort(x)
3677
assert_equal(sortedx._data, [1, 2, 3, 4])
3678
assert_equal(sortedx._mask, [0, 0, 0, 1])
3679
3680
sortedx = sort(x, endwith=False)
3681
assert_equal(sortedx._data, [4, 1, 2, 3])
3682
assert_equal(sortedx._mask, [1, 0, 0, 0])
3683
3684
x.sort()
3685
assert_equal(x._data, [1, 2, 3, 4])
3686
assert_equal(x._mask, [0, 0, 0, 1])
3687
3688
x = array([1, 4, 2, 3], mask=[0, 1, 0, 0], dtype=np.uint8)
3689
x.sort(endwith=False)
3690
assert_equal(x._data, [4, 1, 2, 3])
3691
assert_equal(x._mask, [1, 0, 0, 0])
3692
3693
x = [1, 4, 2, 3]
3694
sortedx = sort(x)
3695
assert_(not isinstance(sorted, MaskedArray))
3696
3697
x = array([0, 1, -1, -2, 2], mask=nomask, dtype=np.int8)
3698
sortedx = sort(x, endwith=False)
3699
assert_equal(sortedx._data, [-2, -1, 0, 1, 2])
3700
x = array([0, 1, -1, -2, 2], mask=[0, 1, 0, 0, 1], dtype=np.int8)
3701
sortedx = sort(x, endwith=False)
3702
assert_equal(sortedx._data, [1, 2, -2, -1, 0])
3703
assert_equal(sortedx._mask, [1, 1, 0, 0, 0])
3704
3705
x = array([0, -1], dtype=np.int8)
3706
sortedx = sort(x, kind="stable")
3707
assert_equal(sortedx, array([-1, 0], dtype=np.int8))
3708
3709
def test_stable_sort(self):
3710
x = array([1, 2, 3, 1, 2, 3], dtype=np.uint8)
3711
expected = array([0, 3, 1, 4, 2, 5])
3712
computed = argsort(x, kind='stable')
3713
assert_equal(computed, expected)
3714
3715
def test_argsort_matches_sort(self):
3716
x = array([1, 4, 2, 3], mask=[0, 1, 0, 0], dtype=np.uint8)
3717
3718
for kwargs in [{},
3719
{"endwith": True},
3720
{"endwith": False},
3721
{"fill_value": 2},
3722
{"fill_value": 2, "endwith": True},
3723
{"fill_value": 2, "endwith": False}]:
3724
sortedx = sort(x, **kwargs)
3725
argsortedx = x[argsort(x, **kwargs)]
3726
assert_equal(sortedx._data, argsortedx._data)
3727
assert_equal(sortedx._mask, argsortedx._mask)
3728
3729
def test_sort_2d(self):
3730
# Check sort of 2D array.
3731
# 2D array w/o mask
3732
a = masked_array([[8, 4, 1], [2, 0, 9]])
3733
a.sort(0)
3734
assert_equal(a, [[2, 0, 1], [8, 4, 9]])
3735
a = masked_array([[8, 4, 1], [2, 0, 9]])
3736
a.sort(1)
3737
assert_equal(a, [[1, 4, 8], [0, 2, 9]])
3738
# 2D array w/mask
3739
a = masked_array([[8, 4, 1], [2, 0, 9]], mask=[[1, 0, 0], [0, 0, 1]])
3740
a.sort(0)
3741
assert_equal(a, [[2, 0, 1], [8, 4, 9]])
3742
assert_equal(a._mask, [[0, 0, 0], [1, 0, 1]])
3743
a = masked_array([[8, 4, 1], [2, 0, 9]], mask=[[1, 0, 0], [0, 0, 1]])
3744
a.sort(1)
3745
assert_equal(a, [[1, 4, 8], [0, 2, 9]])
3746
assert_equal(a._mask, [[0, 0, 1], [0, 0, 1]])
3747
# 3D
3748
a = masked_array([[[7, 8, 9], [4, 5, 6], [1, 2, 3]],
3749
[[1, 2, 3], [7, 8, 9], [4, 5, 6]],
3750
[[7, 8, 9], [1, 2, 3], [4, 5, 6]],
3751
[[4, 5, 6], [1, 2, 3], [7, 8, 9]]])
3752
a[a % 4 == 0] = masked
3753
am = a.copy()
3754
an = a.filled(99)
3755
am.sort(0)
3756
an.sort(0)
3757
assert_equal(am, an)
3758
am = a.copy()
3759
an = a.filled(99)
3760
am.sort(1)
3761
an.sort(1)
3762
assert_equal(am, an)
3763
am = a.copy()
3764
an = a.filled(99)
3765
am.sort(2)
3766
an.sort(2)
3767
assert_equal(am, an)
3768
3769
def test_sort_flexible(self):
3770
# Test sort on structured dtype.
3771
a = array(
3772
data=[(3, 3), (3, 2), (2, 2), (2, 1), (1, 0), (1, 1), (1, 2)],
3773
mask=[(0, 0), (0, 1), (0, 0), (0, 0), (1, 0), (0, 0), (0, 0)],
3774
dtype=[('A', int), ('B', int)])
3775
mask_last = array(
3776
data=[(1, 1), (1, 2), (2, 1), (2, 2), (3, 3), (3, 2), (1, 0)],
3777
mask=[(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 1), (1, 0)],
3778
dtype=[('A', int), ('B', int)])
3779
mask_first = array(
3780
data=[(1, 0), (1, 1), (1, 2), (2, 1), (2, 2), (3, 2), (3, 3)],
3781
mask=[(1, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 1), (0, 0)],
3782
dtype=[('A', int), ('B', int)])
3783
3784
test = sort(a)
3785
assert_equal(test, mask_last)
3786
assert_equal(test.mask, mask_last.mask)
3787
3788
test = sort(a, endwith=False)
3789
assert_equal(test, mask_first)
3790
assert_equal(test.mask, mask_first.mask)
3791
3792
# Test sort on dtype with subarray (gh-8069)
3793
# Just check that the sort does not error, structured array subarrays
3794
# are treated as byte strings and that leads to differing behavior
3795
# depending on endianness and `endwith`.
3796
dt = np.dtype([('v', int, 2)])
3797
a = a.view(dt)
3798
test = sort(a)
3799
test = sort(a, endwith=False)
3800
3801
def test_argsort(self):
3802
# Test argsort
3803
a = array([1, 5, 2, 4, 3], mask=[1, 0, 0, 1, 0])
3804
assert_equal(np.argsort(a), argsort(a))
3805
3806
def test_squeeze(self):
3807
# Check squeeze
3808
data = masked_array([[1, 2, 3]])
3809
assert_equal(data.squeeze(), [1, 2, 3])
3810
data = masked_array([[1, 2, 3]], mask=[[1, 1, 1]])
3811
assert_equal(data.squeeze(), [1, 2, 3])
3812
assert_equal(data.squeeze()._mask, [1, 1, 1])
3813
3814
# normal ndarrays return a view
3815
arr = np.array([[1]])
3816
arr_sq = arr.squeeze()
3817
assert_equal(arr_sq, 1)
3818
arr_sq[...] = 2
3819
assert_equal(arr[0, 0], 2)
3820
3821
# so maskedarrays should too
3822
m_arr = masked_array([[1]], mask=True)
3823
m_arr_sq = m_arr.squeeze()
3824
assert_(m_arr_sq is not np.ma.masked)
3825
assert_equal(m_arr_sq.mask, True)
3826
m_arr_sq[...] = 2
3827
assert_equal(m_arr[0, 0], 2)
3828
3829
def test_swapaxes(self):
3830
# Tests swapaxes on MaskedArrays.
3831
x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928,
3832
8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
3833
3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
3834
6.04, 9.63, 7.712, 3.382, 4.489, 6.479,
3835
7.189, 9.645, 5.395, 4.961, 9.894, 2.893,
3836
7.357, 9.828, 6.272, 3.758, 6.693, 0.993])
3837
m = np.array([0, 1, 0, 1, 0, 0,
3838
1, 0, 1, 1, 0, 1,
3839
0, 0, 0, 1, 0, 1,
3840
0, 0, 0, 1, 1, 1,
3841
1, 0, 0, 1, 0, 0,
3842
0, 0, 1, 0, 1, 0])
3843
mX = array(x, mask=m).reshape(6, 6)
3844
mXX = mX.reshape(3, 2, 2, 3)
3845
3846
mXswapped = mX.swapaxes(0, 1)
3847
assert_equal(mXswapped[-1], mX[:, -1])
3848
3849
mXXswapped = mXX.swapaxes(0, 2)
3850
assert_equal(mXXswapped.shape, (2, 2, 3, 3))
3851
3852
def test_take(self):
3853
# Tests take
3854
x = masked_array([10, 20, 30, 40], [0, 1, 0, 1])
3855
assert_equal(x.take([0, 0, 3]), masked_array([10, 10, 40], [0, 0, 1]))
3856
assert_equal(x.take([0, 0, 3]), x[[0, 0, 3]])
3857
assert_equal(x.take([[0, 1], [0, 1]]),
3858
masked_array([[10, 20], [10, 20]], [[0, 1], [0, 1]]))
3859
3860
# assert_equal crashes when passed np.ma.mask
3861
assert_(x[1] is np.ma.masked)
3862
assert_(x.take(1) is np.ma.masked)
3863
3864
x = array([[10, 20, 30], [40, 50, 60]], mask=[[0, 0, 1], [1, 0, 0, ]])
3865
assert_equal(x.take([0, 2], axis=1),
3866
array([[10, 30], [40, 60]], mask=[[0, 1], [1, 0]]))
3867
assert_equal(take(x, [0, 2], axis=1),
3868
array([[10, 30], [40, 60]], mask=[[0, 1], [1, 0]]))
3869
3870
def test_take_masked_indices(self):
3871
# Test take w/ masked indices
3872
a = np.array((40, 18, 37, 9, 22))
3873
indices = np.arange(3)[None, :] + np.arange(5)[:, None]
3874
mindices = array(indices, mask=(indices >= len(a)))
3875
# No mask
3876
test = take(a, mindices, mode='clip')
3877
ctrl = array([[40, 18, 37],
3878
[18, 37, 9],
3879
[37, 9, 22],
3880
[9, 22, 22],
3881
[22, 22, 22]])
3882
assert_equal(test, ctrl)
3883
# Masked indices
3884
test = take(a, mindices)
3885
ctrl = array([[40, 18, 37],
3886
[18, 37, 9],
3887
[37, 9, 22],
3888
[9, 22, 40],
3889
[22, 40, 40]])
3890
ctrl[3, 2] = ctrl[4, 1] = ctrl[4, 2] = masked
3891
assert_equal(test, ctrl)
3892
assert_equal(test.mask, ctrl.mask)
3893
# Masked input + masked indices
3894
a = array((40, 18, 37, 9, 22), mask=(0, 1, 0, 0, 0))
3895
test = take(a, mindices)
3896
ctrl[0, 1] = ctrl[1, 0] = masked
3897
assert_equal(test, ctrl)
3898
assert_equal(test.mask, ctrl.mask)
3899
3900
def test_tolist(self):
3901
# Tests to list
3902
# ... on 1D
3903
x = array(np.arange(12))
3904
x[[1, -2]] = masked
3905
xlist = x.tolist()
3906
assert_(xlist[1] is None)
3907
assert_(xlist[-2] is None)
3908
# ... on 2D
3909
x.shape = (3, 4)
3910
xlist = x.tolist()
3911
ctrl = [[0, None, 2, 3], [4, 5, 6, 7], [8, 9, None, 11]]
3912
assert_equal(xlist[0], [0, None, 2, 3])
3913
assert_equal(xlist[1], [4, 5, 6, 7])
3914
assert_equal(xlist[2], [8, 9, None, 11])
3915
assert_equal(xlist, ctrl)
3916
# ... on structured array w/ masked records
3917
x = array(list(zip([1, 2, 3],
3918
[1.1, 2.2, 3.3],
3919
['one', 'two', 'thr'])),
3920
dtype=[('a', int), ('b', float), ('c', '|S8')])
3921
x[-1] = masked
3922
assert_equal(x.tolist(),
3923
[(1, 1.1, b'one'),
3924
(2, 2.2, b'two'),
3925
(None, None, None)])
3926
# ... on structured array w/ masked fields
3927
a = array([(1, 2,), (3, 4)], mask=[(0, 1), (0, 0)],
3928
dtype=[('a', int), ('b', int)])
3929
test = a.tolist()
3930
assert_equal(test, [[1, None], [3, 4]])
3931
# ... on mvoid
3932
a = a[0]
3933
test = a.tolist()
3934
assert_equal(test, [1, None])
3935
3936
def test_tolist_specialcase(self):
3937
# Test mvoid.tolist: make sure we return a standard Python object
3938
a = array([(0, 1), (2, 3)], dtype=[('a', int), ('b', int)])
3939
# w/o mask: each entry is a np.void whose elements are standard Python
3940
for entry in a:
3941
for item in entry.tolist():
3942
assert_(not isinstance(item, np.generic))
3943
# w/ mask: each entry is a ma.void whose elements should be
3944
# standard Python
3945
a.mask[0] = (0, 1)
3946
for entry in a:
3947
for item in entry.tolist():
3948
assert_(not isinstance(item, np.generic))
3949
3950
def test_toflex(self):
3951
# Test the conversion to records
3952
data = arange(10)
3953
record = data.toflex()
3954
assert_equal(record['_data'], data._data)
3955
assert_equal(record['_mask'], data._mask)
3956
3957
data[[0, 1, 2, -1]] = masked
3958
record = data.toflex()
3959
assert_equal(record['_data'], data._data)
3960
assert_equal(record['_mask'], data._mask)
3961
3962
ndtype = [('i', int), ('s', '|S3'), ('f', float)]
3963
data = array(list(zip(np.arange(10),
3964
'ABCDEFGHIJKLM',
3965
np.random.rand(10))),
3966
dtype=ndtype)
3967
data[[0, 1, 2, -1]] = masked
3968
record = data.toflex()
3969
assert_equal(record['_data'], data._data)
3970
assert_equal(record['_mask'], data._mask)
3971
3972
ndtype = np.dtype("int, (2,3)float, float")
3973
data = array(list(zip(np.arange(10),
3974
np.random.rand(10),
3975
np.random.rand(10))),
3976
dtype=ndtype)
3977
data[[0, 1, 2, -1]] = masked
3978
record = data.toflex()
3979
assert_equal_records(record['_data'], data._data)
3980
assert_equal_records(record['_mask'], data._mask)
3981
3982
def test_fromflex(self):
3983
# Test the reconstruction of a masked_array from a record
3984
a = array([1, 2, 3])
3985
test = fromflex(a.toflex())
3986
assert_equal(test, a)
3987
assert_equal(test.mask, a.mask)
3988
3989
a = array([1, 2, 3], mask=[0, 0, 1])
3990
test = fromflex(a.toflex())
3991
assert_equal(test, a)
3992
assert_equal(test.mask, a.mask)
3993
3994
a = array([(1, 1.), (2, 2.), (3, 3.)], mask=[(1, 0), (0, 0), (0, 1)],
3995
dtype=[('A', int), ('B', float)])
3996
test = fromflex(a.toflex())
3997
assert_equal(test, a)
3998
assert_equal(test.data, a.data)
3999
4000
def test_arraymethod(self):
4001
# Test a _arraymethod w/ n argument
4002
marray = masked_array([[1, 2, 3, 4, 5]], mask=[0, 0, 1, 0, 0])
4003
control = masked_array([[1], [2], [3], [4], [5]],
4004
mask=[0, 0, 1, 0, 0])
4005
assert_equal(marray.T, control)
4006
assert_equal(marray.transpose(), control)
4007
4008
assert_equal(MaskedArray.cumsum(marray.T, 0), control.cumsum(0))
4009
4010
def test_arraymethod_0d(self):
4011
# gh-9430
4012
x = np.ma.array(42, mask=True)
4013
assert_equal(x.T.mask, x.mask)
4014
assert_equal(x.T.data, x.data)
4015
4016
def test_transpose_view(self):
4017
x = np.ma.array([[1, 2, 3], [4, 5, 6]])
4018
x[0, 1] = np.ma.masked
4019
xt = x.T
4020
4021
xt[1, 0] = 10
4022
xt[0, 1] = np.ma.masked
4023
4024
assert_equal(x.data, xt.T.data)
4025
assert_equal(x.mask, xt.T.mask)
4026
4027
def test_diagonal_view(self):
4028
x = np.ma.zeros((3, 3))
4029
x[0, 0] = 10
4030
x[1, 1] = np.ma.masked
4031
x[2, 2] = 20
4032
xd = x.diagonal()
4033
x[1, 1] = 15
4034
assert_equal(xd.mask, x.diagonal().mask)
4035
assert_equal(xd.data, x.diagonal().data)
4036
4037
4038
class TestMaskedArrayMathMethods:
4039
def _create_data(self):
4040
# Base data definition.
4041
x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928,
4042
8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
4043
3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
4044
6.04, 9.63, 7.712, 3.382, 4.489, 6.479,
4045
7.189, 9.645, 5.395, 4.961, 9.894, 2.893,
4046
7.357, 9.828, 6.272, 3.758, 6.693, 0.993])
4047
X = x.reshape(6, 6)
4048
XX = x.reshape(3, 2, 2, 3)
4049
4050
m = np.array([0, 1, 0, 1, 0, 0,
4051
1, 0, 1, 1, 0, 1,
4052
0, 0, 0, 1, 0, 1,
4053
0, 0, 0, 1, 1, 1,
4054
1, 0, 0, 1, 0, 0,
4055
0, 0, 1, 0, 1, 0])
4056
mx = array(data=x, mask=m)
4057
mX = array(data=X, mask=m.reshape(X.shape))
4058
mXX = array(data=XX, mask=m.reshape(XX.shape))
4059
4060
m2 = np.array([1, 1, 0, 1, 0, 0,
4061
1, 1, 1, 1, 0, 1,
4062
0, 0, 1, 1, 0, 1,
4063
0, 0, 0, 1, 1, 1,
4064
1, 0, 0, 1, 1, 0,
4065
0, 0, 1, 0, 1, 1])
4066
m2x = array(data=x, mask=m2)
4067
m2X = array(data=X, mask=m2.reshape(X.shape))
4068
m2XX = array(data=XX, mask=m2.reshape(XX.shape))
4069
return x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX
4070
4071
def test_cumsumprod(self):
4072
# Tests cumsum & cumprod on MaskedArrays.
4073
mX = self._create_data()[5]
4074
mXcp = mX.cumsum(0)
4075
assert_equal(mXcp._data, mX.filled(0).cumsum(0))
4076
mXcp = mX.cumsum(1)
4077
assert_equal(mXcp._data, mX.filled(0).cumsum(1))
4078
4079
mXcp = mX.cumprod(0)
4080
assert_equal(mXcp._data, mX.filled(1).cumprod(0))
4081
mXcp = mX.cumprod(1)
4082
assert_equal(mXcp._data, mX.filled(1).cumprod(1))
4083
4084
def test_cumsumprod_with_output(self):
4085
# Tests cumsum/cumprod w/ output
4086
xm = array(np.random.uniform(0, 10, 12)).reshape(3, 4)
4087
xm[:, 0] = xm[0] = xm[-1, -1] = masked
4088
4089
for funcname in ('cumsum', 'cumprod'):
4090
npfunc = getattr(np, funcname)
4091
xmmeth = getattr(xm, funcname)
4092
4093
# A ndarray as explicit input
4094
output = np.empty((3, 4), dtype=float)
4095
output.fill(-9999)
4096
result = npfunc(xm, axis=0, out=output)
4097
# ... the result should be the given output
4098
assert_(result is output)
4099
assert_equal(result, xmmeth(axis=0, out=output))
4100
4101
output = empty((3, 4), dtype=int)
4102
result = xmmeth(axis=0, out=output)
4103
assert_(result is output)
4104
4105
def test_ptp(self):
4106
# Tests ptp on MaskedArrays.
4107
_, X, _, m, mx, mX, _, _, _, _ = self._create_data()
4108
(n, m) = X.shape
4109
assert_equal(mx.ptp(), np.ptp(mx.compressed()))
4110
rows = np.zeros(n, float)
4111
cols = np.zeros(m, float)
4112
for k in range(m):
4113
cols[k] = np.ptp(mX[:, k].compressed())
4114
for k in range(n):
4115
rows[k] = np.ptp(mX[k].compressed())
4116
assert_equal(mX.ptp(0), cols)
4117
assert_equal(mX.ptp(1), rows)
4118
4119
def test_add_object(self):
4120
x = masked_array(['a', 'b'], mask=[1, 0], dtype=object)
4121
y = x + 'x'
4122
assert_equal(y[1], 'bx')
4123
assert_(y.mask[0])
4124
4125
def test_sum_object(self):
4126
# Test sum on object dtype
4127
a = masked_array([1, 2, 3], mask=[1, 0, 0], dtype=object)
4128
assert_equal(a.sum(), 5)
4129
a = masked_array([[1, 2, 3], [4, 5, 6]], dtype=object)
4130
assert_equal(a.sum(axis=0), [5, 7, 9])
4131
4132
def test_prod_object(self):
4133
# Test prod on object dtype
4134
a = masked_array([1, 2, 3], mask=[1, 0, 0], dtype=object)
4135
assert_equal(a.prod(), 2 * 3)
4136
a = masked_array([[1, 2, 3], [4, 5, 6]], dtype=object)
4137
assert_equal(a.prod(axis=0), [4, 10, 18])
4138
4139
def test_meananom_object(self):
4140
# Test mean/anom on object dtype
4141
a = masked_array([1, 2, 3], dtype=object)
4142
assert_equal(a.mean(), 2)
4143
assert_equal(a.anom(), [-1, 0, 1])
4144
4145
def test_anom_shape(self):
4146
a = masked_array([1, 2, 3])
4147
assert_equal(a.anom().shape, a.shape)
4148
a.mask = True
4149
assert_equal(a.anom().shape, a.shape)
4150
assert_(np.ma.is_masked(a.anom()))
4151
4152
def test_anom(self):
4153
a = masked_array(np.arange(1, 7).reshape(2, 3))
4154
assert_almost_equal(a.anom(),
4155
[[-2.5, -1.5, -0.5], [0.5, 1.5, 2.5]])
4156
assert_almost_equal(a.anom(axis=0),
4157
[[-1.5, -1.5, -1.5], [1.5, 1.5, 1.5]])
4158
assert_almost_equal(a.anom(axis=1),
4159
[[-1., 0., 1.], [-1., 0., 1.]])
4160
a.mask = [[0, 0, 1], [0, 1, 0]]
4161
mval = -99
4162
assert_almost_equal(a.anom().filled(mval),
4163
[[-2.25, -1.25, mval], [0.75, mval, 2.75]])
4164
assert_almost_equal(a.anom(axis=0).filled(mval),
4165
[[-1.5, 0.0, mval], [1.5, mval, 0.0]])
4166
assert_almost_equal(a.anom(axis=1).filled(mval),
4167
[[-0.5, 0.5, mval], [-1.0, mval, 1.0]])
4168
4169
def test_trace(self):
4170
# Tests trace on MaskedArrays.
4171
_, X, _, _, _, mX, _, _, _, _ = self._create_data()
4172
mXdiag = mX.diagonal()
4173
assert_equal(mX.trace(), mX.diagonal().compressed().sum())
4174
assert_almost_equal(mX.trace(),
4175
X.trace() - sum(mXdiag.mask * X.diagonal(),
4176
axis=0))
4177
assert_equal(np.trace(mX), mX.trace())
4178
4179
# gh-5560
4180
arr = np.arange(2 * 4 * 4).reshape(2, 4, 4)
4181
m_arr = np.ma.masked_array(arr, False)
4182
assert_equal(arr.trace(axis1=1, axis2=2), m_arr.trace(axis1=1, axis2=2))
4183
4184
def test_dot(self):
4185
# Tests dot on MaskedArrays.
4186
_, _, _, _, mx, mX, mXX, _, _, _ = self._create_data()
4187
fx = mx.filled(0)
4188
r = mx.dot(mx)
4189
assert_almost_equal(r.filled(0), fx.dot(fx))
4190
assert_(r.mask is nomask)
4191
4192
fX = mX.filled(0)
4193
r = mX.dot(mX)
4194
assert_almost_equal(r.filled(0), fX.dot(fX))
4195
assert_(r.mask[1, 3])
4196
r1 = empty_like(r)
4197
mX.dot(mX, out=r1)
4198
assert_almost_equal(r, r1)
4199
4200
mYY = mXX.swapaxes(-1, -2)
4201
fXX, fYY = mXX.filled(0), mYY.filled(0)
4202
r = mXX.dot(mYY)
4203
assert_almost_equal(r.filled(0), fXX.dot(fYY))
4204
r1 = empty_like(r)
4205
mXX.dot(mYY, out=r1)
4206
assert_almost_equal(r, r1)
4207
4208
def test_dot_shape_mismatch(self):
4209
# regression test
4210
x = masked_array([[1, 2], [3, 4]], mask=[[0, 1], [0, 0]])
4211
y = masked_array([[1, 2], [3, 4]], mask=[[0, 1], [0, 0]])
4212
z = masked_array([[0, 1], [3, 3]])
4213
x.dot(y, out=z)
4214
assert_almost_equal(z.filled(0), [[1, 0], [15, 16]])
4215
assert_almost_equal(z.mask, [[0, 1], [0, 0]])
4216
4217
def test_varmean_nomask(self):
4218
# gh-5769
4219
foo = array([1, 2, 3, 4], dtype='f8')
4220
bar = array([1, 2, 3, 4], dtype='f8')
4221
assert_equal(type(foo.mean()), np.float64)
4222
assert_equal(type(foo.var()), np.float64)
4223
assert (foo.mean() == bar.mean()) is np.bool(True)
4224
4225
# check array type is preserved and out works
4226
foo = array(np.arange(16).reshape((4, 4)), dtype='f8')
4227
bar = empty(4, dtype='f4')
4228
assert_equal(type(foo.mean(axis=1)), MaskedArray)
4229
assert_equal(type(foo.var(axis=1)), MaskedArray)
4230
assert_(foo.mean(axis=1, out=bar) is bar)
4231
assert_(foo.var(axis=1, out=bar) is bar)
4232
4233
def test_varstd(self):
4234
# Tests var & std on MaskedArrays.
4235
_, X, XX, _, _, mX, mXX, _, _, _ = self._create_data()
4236
assert_almost_equal(mX.var(axis=None), mX.compressed().var())
4237
assert_almost_equal(mX.std(axis=None), mX.compressed().std())
4238
assert_almost_equal(mX.std(axis=None, ddof=1),
4239
mX.compressed().std(ddof=1))
4240
assert_almost_equal(mX.var(axis=None, ddof=1),
4241
mX.compressed().var(ddof=1))
4242
assert_equal(mXX.var(axis=3).shape, XX.var(axis=3).shape)
4243
assert_equal(mX.var().shape, X.var().shape)
4244
(mXvar0, mXvar1) = (mX.var(axis=0), mX.var(axis=1))
4245
assert_almost_equal(mX.var(axis=None, ddof=2),
4246
mX.compressed().var(ddof=2))
4247
assert_almost_equal(mX.std(axis=None, ddof=2),
4248
mX.compressed().std(ddof=2))
4249
for k in range(6):
4250
assert_almost_equal(mXvar1[k], mX[k].compressed().var())
4251
assert_almost_equal(mXvar0[k], mX[:, k].compressed().var())
4252
assert_almost_equal(np.sqrt(mXvar0[k]),
4253
mX[:, k].compressed().std())
4254
4255
@pytest.mark.filterwarnings(WARNING_MARK_SPEC)
4256
def test_varstd_specialcases(self):
4257
# Test a special case for var
4258
nout = np.array(-1, dtype=float)
4259
mout = array(-1, dtype=float)
4260
4261
x = array(arange(10), mask=True)
4262
for methodname in ('var', 'std'):
4263
method = getattr(x, methodname)
4264
assert_(method() is masked)
4265
assert_(method(0) is masked)
4266
assert_(method(-1) is masked)
4267
# Using a masked array as explicit output
4268
method(out=mout)
4269
assert_(mout is not masked)
4270
assert_equal(mout.mask, True)
4271
# Using a ndarray as explicit output
4272
method(out=nout)
4273
assert_(np.isnan(nout))
4274
4275
x = array(arange(10), mask=True)
4276
x[-1] = 9
4277
for methodname in ('var', 'std'):
4278
method = getattr(x, methodname)
4279
assert_(method(ddof=1) is masked)
4280
assert_(method(0, ddof=1) is masked)
4281
assert_(method(-1, ddof=1) is masked)
4282
# Using a masked array as explicit output
4283
method(out=mout, ddof=1)
4284
assert_(mout is not masked)
4285
assert_equal(mout.mask, True)
4286
# Using a ndarray as explicit output
4287
method(out=nout, ddof=1)
4288
assert_(np.isnan(nout))
4289
4290
def test_varstd_ddof(self):
4291
a = array([[1, 1, 0], [1, 1, 0]], mask=[[0, 0, 1], [0, 0, 1]])
4292
test = a.std(axis=0, ddof=0)
4293
assert_equal(test.filled(0), [0, 0, 0])
4294
assert_equal(test.mask, [0, 0, 1])
4295
test = a.std(axis=0, ddof=1)
4296
assert_equal(test.filled(0), [0, 0, 0])
4297
assert_equal(test.mask, [0, 0, 1])
4298
test = a.std(axis=0, ddof=2)
4299
assert_equal(test.filled(0), [0, 0, 0])
4300
assert_equal(test.mask, [1, 1, 1])
4301
4302
def test_diag(self):
4303
# Test diag
4304
x = arange(9).reshape((3, 3))
4305
x[1, 1] = masked
4306
out = np.diag(x)
4307
assert_equal(out, [0, 4, 8])
4308
out = diag(x)
4309
assert_equal(out, [0, 4, 8])
4310
assert_equal(out.mask, [0, 1, 0])
4311
out = diag(out)
4312
control = array([[0, 0, 0], [0, 4, 0], [0, 0, 8]],
4313
mask=[[0, 0, 0], [0, 1, 0], [0, 0, 0]])
4314
assert_equal(out, control)
4315
4316
def test_axis_methods_nomask(self):
4317
# Test the combination nomask & methods w/ axis
4318
a = array([[1, 2, 3], [4, 5, 6]])
4319
4320
assert_equal(a.sum(0), [5, 7, 9])
4321
assert_equal(a.sum(-1), [6, 15])
4322
assert_equal(a.sum(1), [6, 15])
4323
4324
assert_equal(a.prod(0), [4, 10, 18])
4325
assert_equal(a.prod(-1), [6, 120])
4326
assert_equal(a.prod(1), [6, 120])
4327
4328
assert_equal(a.min(0), [1, 2, 3])
4329
assert_equal(a.min(-1), [1, 4])
4330
assert_equal(a.min(1), [1, 4])
4331
4332
assert_equal(a.max(0), [4, 5, 6])
4333
assert_equal(a.max(-1), [3, 6])
4334
assert_equal(a.max(1), [3, 6])
4335
4336
@pytest.mark.thread_unsafe(reason="crashes with low memory")
4337
@requires_memory(free_bytes=2 * 10000 * 1000 * 2)
4338
def test_mean_overflow(self):
4339
# Test overflow in masked arrays
4340
# gh-20272
4341
a = masked_array(np.full((10000, 10000), 65535, dtype=np.uint16),
4342
mask=np.zeros((10000, 10000)))
4343
assert_equal(a.mean(), 65535.0)
4344
4345
def test_diff_with_prepend(self):
4346
# GH 22465
4347
x = np.array([1, 2, 2, 3, 4, 2, 1, 1])
4348
4349
a = np.ma.masked_equal(x[3:], value=2)
4350
a_prep = np.ma.masked_equal(x[:3], value=2)
4351
diff1 = np.ma.diff(a, prepend=a_prep, axis=0)
4352
4353
b = np.ma.masked_equal(x, value=2)
4354
diff2 = np.ma.diff(b, axis=0)
4355
4356
assert_(np.ma.allequal(diff1, diff2))
4357
4358
def test_diff_with_append(self):
4359
# GH 22465
4360
x = np.array([1, 2, 2, 3, 4, 2, 1, 1])
4361
4362
a = np.ma.masked_equal(x[:3], value=2)
4363
a_app = np.ma.masked_equal(x[3:], value=2)
4364
diff1 = np.ma.diff(a, append=a_app, axis=0)
4365
4366
b = np.ma.masked_equal(x, value=2)
4367
diff2 = np.ma.diff(b, axis=0)
4368
4369
assert_(np.ma.allequal(diff1, diff2))
4370
4371
def test_diff_with_dim_0(self):
4372
with pytest.raises(
4373
ValueError,
4374
match="diff requires input that is at least one dimensional"
4375
):
4376
np.ma.diff(np.array(1))
4377
4378
def test_diff_with_n_0(self):
4379
a = np.ma.masked_equal([1, 2, 2, 3, 4, 2, 1, 1], value=2)
4380
diff = np.ma.diff(a, n=0, axis=0)
4381
4382
assert_(np.ma.allequal(a, diff))
4383
4384
4385
class TestMaskedArrayMathMethodsComplex:
4386
# Test class for miscellaneous MaskedArrays methods.
4387
def _create_data(self):
4388
# Base data definition.
4389
x = np.array([8.375j, 7.545j, 8.828j, 8.5j, 1.757j, 5.928,
4390
8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
4391
3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
4392
6.04, 9.63, 7.712, 3.382, 4.489, 6.479j,
4393
7.189j, 9.645, 5.395, 4.961, 9.894, 2.893,
4394
7.357, 9.828, 6.272, 3.758, 6.693, 0.993j])
4395
X = x.reshape(6, 6)
4396
XX = x.reshape(3, 2, 2, 3)
4397
4398
m = np.array([0, 1, 0, 1, 0, 0,
4399
1, 0, 1, 1, 0, 1,
4400
0, 0, 0, 1, 0, 1,
4401
0, 0, 0, 1, 1, 1,
4402
1, 0, 0, 1, 0, 0,
4403
0, 0, 1, 0, 1, 0])
4404
mx = array(data=x, mask=m)
4405
mX = array(data=X, mask=m.reshape(X.shape))
4406
mXX = array(data=XX, mask=m.reshape(XX.shape))
4407
4408
m2 = np.array([1, 1, 0, 1, 0, 0,
4409
1, 1, 1, 1, 0, 1,
4410
0, 0, 1, 1, 0, 1,
4411
0, 0, 0, 1, 1, 1,
4412
1, 0, 0, 1, 1, 0,
4413
0, 0, 1, 0, 1, 1])
4414
m2x = array(data=x, mask=m2)
4415
m2X = array(data=X, mask=m2.reshape(X.shape))
4416
m2XX = array(data=XX, mask=m2.reshape(XX.shape))
4417
return x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX
4418
4419
def test_varstd(self):
4420
# Tests var & std on MaskedArrays.
4421
_, X, XX, _, _, mX, mXX, _, _, _ = self._create_data()
4422
assert_almost_equal(mX.var(axis=None), mX.compressed().var())
4423
assert_almost_equal(mX.std(axis=None), mX.compressed().std())
4424
assert_equal(mXX.var(axis=3).shape, XX.var(axis=3).shape)
4425
assert_equal(mX.var().shape, X.var().shape)
4426
(mXvar0, mXvar1) = (mX.var(axis=0), mX.var(axis=1))
4427
assert_almost_equal(mX.var(axis=None, ddof=2),
4428
mX.compressed().var(ddof=2))
4429
assert_almost_equal(mX.std(axis=None, ddof=2),
4430
mX.compressed().std(ddof=2))
4431
for k in range(6):
4432
assert_almost_equal(mXvar1[k], mX[k].compressed().var())
4433
assert_almost_equal(mXvar0[k], mX[:, k].compressed().var())
4434
assert_almost_equal(np.sqrt(mXvar0[k]),
4435
mX[:, k].compressed().std())
4436
4437
4438
class TestMaskedArrayFunctions:
4439
# Test class for miscellaneous functions.
4440
def test_masked_where_bool(self):
4441
x = [1, 2]
4442
y = masked_where(False, x)
4443
assert_equal(y, [1, 2])
4444
assert_equal(y[1], 2)
4445
4446
def test_masked_equal_wlist(self):
4447
x = [1, 2, 3]
4448
mx = masked_equal(x, 3)
4449
assert_equal(mx, x)
4450
assert_equal(mx._mask, [0, 0, 1])
4451
mx = masked_not_equal(x, 3)
4452
assert_equal(mx, x)
4453
assert_equal(mx._mask, [1, 1, 0])
4454
4455
def test_masked_equal_fill_value(self):
4456
x = [1, 2, 3]
4457
mx = masked_equal(x, 3)
4458
assert_equal(mx._mask, [0, 0, 1])
4459
assert_equal(mx.fill_value, 3)
4460
4461
def test_masked_where_condition(self):
4462
# Tests masking functions.
4463
x = array([1., 2., 3., 4., 5.])
4464
x[2] = masked
4465
assert_equal(masked_where(greater(x, 2), x), masked_greater(x, 2))
4466
assert_equal(masked_where(greater_equal(x, 2), x),
4467
masked_greater_equal(x, 2))
4468
assert_equal(masked_where(less(x, 2), x), masked_less(x, 2))
4469
assert_equal(masked_where(less_equal(x, 2), x),
4470
masked_less_equal(x, 2))
4471
assert_equal(masked_where(not_equal(x, 2), x), masked_not_equal(x, 2))
4472
assert_equal(masked_where(equal(x, 2), x), masked_equal(x, 2))
4473
assert_equal(masked_where(not_equal(x, 2), x), masked_not_equal(x, 2))
4474
assert_equal(masked_where([1, 1, 0, 0, 0], [1, 2, 3, 4, 5]),
4475
[99, 99, 3, 4, 5])
4476
4477
def test_masked_where_oddities(self):
4478
# Tests some generic features.
4479
atest = ones((10, 10, 10), dtype=float)
4480
btest = zeros(atest.shape, MaskType)
4481
ctest = masked_where(btest, atest)
4482
assert_equal(atest, ctest)
4483
4484
def test_masked_where_shape_constraint(self):
4485
a = arange(10)
4486
with assert_raises(IndexError):
4487
masked_equal(1, a)
4488
test = masked_equal(a, 1)
4489
assert_equal(test.mask, [0, 1, 0, 0, 0, 0, 0, 0, 0, 0])
4490
4491
def test_masked_where_structured(self):
4492
# test that masked_where on a structured array sets a structured
4493
# mask (see issue #2972)
4494
a = np.zeros(10, dtype=[("A", "<f2"), ("B", "<f4")])
4495
with np.errstate(over="ignore"):
4496
# NOTE: The float16 "uses" 1e20 as mask, which overflows to inf
4497
# and warns. Unrelated to this test, but probably undesired.
4498
# But NumPy previously did not warn for this overflow.
4499
am = np.ma.masked_where(a["A"] < 5, a)
4500
assert_equal(am.mask.dtype.names, am.dtype.names)
4501
assert_equal(am["A"],
4502
np.ma.masked_array(np.zeros(10), np.ones(10)))
4503
4504
def test_masked_where_mismatch(self):
4505
# gh-4520
4506
x = np.arange(10)
4507
y = np.arange(5)
4508
assert_raises(IndexError, np.ma.masked_where, y > 6, x)
4509
4510
def test_masked_otherfunctions(self):
4511
assert_equal(masked_inside(list(range(5)), 1, 3),
4512
[0, 199, 199, 199, 4])
4513
assert_equal(masked_outside(list(range(5)), 1, 3), [199, 1, 2, 3, 199])
4514
assert_equal(masked_inside(array(list(range(5)),
4515
mask=[1, 0, 0, 0, 0]), 1, 3).mask,
4516
[1, 1, 1, 1, 0])
4517
assert_equal(masked_outside(array(list(range(5)),
4518
mask=[0, 1, 0, 0, 0]), 1, 3).mask,
4519
[1, 1, 0, 0, 1])
4520
assert_equal(masked_equal(array(list(range(5)),
4521
mask=[1, 0, 0, 0, 0]), 2).mask,
4522
[1, 0, 1, 0, 0])
4523
assert_equal(masked_not_equal(array([2, 2, 1, 2, 1],
4524
mask=[1, 0, 0, 0, 0]), 2).mask,
4525
[1, 0, 1, 0, 1])
4526
4527
def test_round(self):
4528
a = array([1.23456, 2.34567, 3.45678, 4.56789, 5.67890],
4529
mask=[0, 1, 0, 0, 0])
4530
assert_equal(a.round(), [1., 2., 3., 5., 6.])
4531
assert_equal(a.round(1), [1.2, 2.3, 3.5, 4.6, 5.7])
4532
assert_equal(a.round(3), [1.235, 2.346, 3.457, 4.568, 5.679])
4533
b = empty_like(a)
4534
a.round(out=b)
4535
assert_equal(b, [1., 2., 3., 5., 6.])
4536
4537
x = array([1., 2., 3., 4., 5.])
4538
c = array([1, 1, 1, 0, 0])
4539
x[2] = masked
4540
z = where(c, x, -x)
4541
assert_equal(z, [1., 2., 0., -4., -5])
4542
c[0] = masked
4543
z = where(c, x, -x)
4544
assert_equal(z, [1., 2., 0., -4., -5])
4545
assert_(z[0] is masked)
4546
assert_(z[1] is not masked)
4547
assert_(z[2] is masked)
4548
4549
def test_round_with_output(self):
4550
# Testing round with an explicit output
4551
4552
xm = array(np.random.uniform(0, 10, 12)).reshape(3, 4)
4553
xm[:, 0] = xm[0] = xm[-1, -1] = masked
4554
4555
# A ndarray as explicit input
4556
output = np.empty((3, 4), dtype=float)
4557
output.fill(-9999)
4558
result = np.round(xm, decimals=2, out=output)
4559
# ... the result should be the given output
4560
assert_(result is output)
4561
assert_equal(result, xm.round(decimals=2, out=output))
4562
4563
output = empty((3, 4), dtype=float)
4564
result = xm.round(decimals=2, out=output)
4565
assert_(result is output)
4566
4567
def test_round_with_scalar(self):
4568
# Testing round with scalar/zero dimension input
4569
# GH issue 2244
4570
a = array(1.1, mask=[False])
4571
assert_equal(a.round(), 1)
4572
4573
a = array(1.1, mask=[True])
4574
assert_(a.round() is masked)
4575
4576
a = array(1.1, mask=[False])
4577
output = np.empty(1, dtype=float)
4578
output.fill(-9999)
4579
a.round(out=output)
4580
assert_equal(output, 1)
4581
4582
a = array(1.1, mask=[False])
4583
output = array(-9999., mask=[True])
4584
a.round(out=output)
4585
assert_equal(output[()], 1)
4586
4587
a = array(1.1, mask=[True])
4588
output = array(-9999., mask=[False])
4589
a.round(out=output)
4590
assert_(output[()] is masked)
4591
4592
def test_identity(self):
4593
a = identity(5)
4594
assert_(isinstance(a, MaskedArray))
4595
assert_equal(a, np.identity(5))
4596
4597
def test_power(self):
4598
x = -1.1
4599
assert_almost_equal(power(x, 2.), 1.21)
4600
assert_(power(x, masked) is masked)
4601
x = array([-1.1, -1.1, 1.1, 1.1, 0.])
4602
b = array([0.5, 2., 0.5, 2., -1.], mask=[0, 0, 0, 0, 1])
4603
y = power(x, b)
4604
assert_almost_equal(y, [0, 1.21, 1.04880884817, 1.21, 0.])
4605
assert_equal(y._mask, [1, 0, 0, 0, 1])
4606
b.mask = nomask
4607
y = power(x, b)
4608
assert_equal(y._mask, [1, 0, 0, 0, 1])
4609
z = x ** b
4610
assert_equal(z._mask, y._mask)
4611
assert_almost_equal(z, y)
4612
assert_almost_equal(z._data, y._data)
4613
x **= b
4614
assert_equal(x._mask, y._mask)
4615
assert_almost_equal(x, y)
4616
assert_almost_equal(x._data, y._data)
4617
4618
def test_power_with_broadcasting(self):
4619
# Test power w/ broadcasting
4620
a2 = np.array([[1., 2., 3.], [4., 5., 6.]])
4621
a2m = array(a2, mask=[[1, 0, 0], [0, 0, 1]])
4622
b1 = np.array([2, 4, 3])
4623
b2 = np.array([b1, b1])
4624
b2m = array(b2, mask=[[0, 1, 0], [0, 1, 0]])
4625
4626
ctrl = array([[1 ** 2, 2 ** 4, 3 ** 3], [4 ** 2, 5 ** 4, 6 ** 3]],
4627
mask=[[1, 1, 0], [0, 1, 1]])
4628
# No broadcasting, base & exp w/ mask
4629
test = a2m ** b2m
4630
assert_equal(test, ctrl)
4631
assert_equal(test.mask, ctrl.mask)
4632
# No broadcasting, base w/ mask, exp w/o mask
4633
test = a2m ** b2
4634
assert_equal(test, ctrl)
4635
assert_equal(test.mask, a2m.mask)
4636
# No broadcasting, base w/o mask, exp w/ mask
4637
test = a2 ** b2m
4638
assert_equal(test, ctrl)
4639
assert_equal(test.mask, b2m.mask)
4640
4641
ctrl = array([[2 ** 2, 4 ** 4, 3 ** 3], [2 ** 2, 4 ** 4, 3 ** 3]],
4642
mask=[[0, 1, 0], [0, 1, 0]])
4643
test = b1 ** b2m
4644
assert_equal(test, ctrl)
4645
assert_equal(test.mask, ctrl.mask)
4646
test = b2m ** b1
4647
assert_equal(test, ctrl)
4648
assert_equal(test.mask, ctrl.mask)
4649
4650
@pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
4651
def test_where(self):
4652
# Test the where function
4653
x = np.array([1., 1., 1., -2., pi / 2.0, 4., 5., -10., 10., 1., 2., 3.])
4654
y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
4655
m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
4656
m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
4657
xm = masked_array(x, mask=m1)
4658
ym = masked_array(y, mask=m2)
4659
xm.set_fill_value(1e+20)
4660
4661
d = where(xm > 2, xm, -9)
4662
assert_equal(d, [-9., -9., -9., -9., -9., 4.,
4663
-9., -9., 10., -9., -9., 3.])
4664
assert_equal(d._mask, xm._mask)
4665
d = where(xm > 2, -9, ym)
4666
assert_equal(d, [5., 0., 3., 2., -1., -9.,
4667
-9., -10., -9., 1., 0., -9.])
4668
assert_equal(d._mask, [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0])
4669
d = where(xm > 2, xm, masked)
4670
assert_equal(d, [-9., -9., -9., -9., -9., 4.,
4671
-9., -9., 10., -9., -9., 3.])
4672
tmp = xm._mask.copy()
4673
tmp[(xm <= 2).filled(True)] = True
4674
assert_equal(d._mask, tmp)
4675
4676
with np.errstate(invalid="warn"):
4677
# The fill value is 1e20, it cannot be converted to `int`:
4678
with pytest.warns(RuntimeWarning, match="invalid value"):
4679
ixm = xm.astype(int)
4680
d = where(ixm > 2, ixm, masked)
4681
assert_equal(d, [-9, -9, -9, -9, -9, 4, -9, -9, 10, -9, -9, 3])
4682
assert_equal(d.dtype, ixm.dtype)
4683
4684
def test_where_object(self):
4685
a = np.array(None)
4686
b = masked_array(None)
4687
r = b.copy()
4688
assert_equal(np.ma.where(True, a, a), r)
4689
assert_equal(np.ma.where(True, b, b), r)
4690
4691
def test_where_with_masked_choice(self):
4692
x = arange(10)
4693
x[3] = masked
4694
c = x >= 8
4695
# Set False to masked
4696
z = where(c, x, masked)
4697
assert_(z.dtype is x.dtype)
4698
assert_(z[3] is masked)
4699
assert_(z[4] is masked)
4700
assert_(z[7] is masked)
4701
assert_(z[8] is not masked)
4702
assert_(z[9] is not masked)
4703
assert_equal(x, z)
4704
# Set True to masked
4705
z = where(c, masked, x)
4706
assert_(z.dtype is x.dtype)
4707
assert_(z[3] is masked)
4708
assert_(z[4] is not masked)
4709
assert_(z[7] is not masked)
4710
assert_(z[8] is masked)
4711
assert_(z[9] is masked)
4712
4713
def test_where_with_masked_condition(self):
4714
x = array([1., 2., 3., 4., 5.])
4715
c = array([1, 1, 1, 0, 0])
4716
x[2] = masked
4717
z = where(c, x, -x)
4718
assert_equal(z, [1., 2., 0., -4., -5])
4719
c[0] = masked
4720
z = where(c, x, -x)
4721
assert_equal(z, [1., 2., 0., -4., -5])
4722
assert_(z[0] is masked)
4723
assert_(z[1] is not masked)
4724
assert_(z[2] is masked)
4725
4726
x = arange(1, 6)
4727
x[-1] = masked
4728
y = arange(1, 6) * 10
4729
y[2] = masked
4730
c = array([1, 1, 1, 0, 0], mask=[1, 0, 0, 0, 0])
4731
cm = c.filled(1)
4732
z = where(c, x, y)
4733
zm = where(cm, x, y)
4734
assert_equal(z, zm)
4735
assert_(getmask(zm) is nomask)
4736
assert_equal(zm, [1, 2, 3, 40, 50])
4737
z = where(c, masked, 1)
4738
assert_equal(z, [99, 99, 99, 1, 1])
4739
z = where(c, 1, masked)
4740
assert_equal(z, [99, 1, 1, 99, 99])
4741
4742
def test_where_type(self):
4743
# Test the type conservation with where
4744
x = np.arange(4, dtype=np.int32)
4745
y = np.arange(4, dtype=np.float32) * 2.2
4746
test = where(x > 1.5, y, x).dtype
4747
control = np.result_type(np.int32, np.float32)
4748
assert_equal(test, control)
4749
4750
def test_where_broadcast(self):
4751
# Issue 8599
4752
x = np.arange(9).reshape(3, 3)
4753
y = np.zeros(3)
4754
core = np.where([1, 0, 1], x, y)
4755
ma = where([1, 0, 1], x, y)
4756
4757
assert_equal(core, ma)
4758
assert_equal(core.dtype, ma.dtype)
4759
4760
def test_where_structured(self):
4761
# Issue 8600
4762
dt = np.dtype([('a', int), ('b', int)])
4763
x = np.array([(1, 2), (3, 4), (5, 6)], dtype=dt)
4764
y = np.array((10, 20), dtype=dt)
4765
core = np.where([0, 1, 1], x, y)
4766
ma = np.where([0, 1, 1], x, y)
4767
4768
assert_equal(core, ma)
4769
assert_equal(core.dtype, ma.dtype)
4770
4771
def test_where_structured_masked(self):
4772
dt = np.dtype([('a', int), ('b', int)])
4773
x = np.array([(1, 2), (3, 4), (5, 6)], dtype=dt)
4774
4775
ma = where([0, 1, 1], x, masked)
4776
expected = masked_where([1, 0, 0], x)
4777
4778
assert_equal(ma.dtype, expected.dtype)
4779
assert_equal(ma, expected)
4780
assert_equal(ma.mask, expected.mask)
4781
4782
def test_masked_invalid_error(self):
4783
a = np.arange(5, dtype=object)
4784
a[3] = np.inf
4785
a[2] = np.nan
4786
with pytest.raises(TypeError,
4787
match="not supported for the input types"):
4788
np.ma.masked_invalid(a)
4789
4790
def test_masked_invalid_pandas(self):
4791
# getdata() used to be bad for pandas series due to its _data
4792
# attribute. This test is a regression test mainly and may be
4793
# removed if getdata() is adjusted.
4794
class Series:
4795
_data = "nonsense"
4796
4797
def __array__(self, dtype=None, copy=None):
4798
return np.array([5, np.nan, np.inf])
4799
4800
arr = np.ma.masked_invalid(Series())
4801
assert_array_equal(arr._data, np.array(Series()))
4802
assert_array_equal(arr._mask, [False, True, True])
4803
4804
@pytest.mark.parametrize("copy", [True, False])
4805
def test_masked_invalid_full_mask(self, copy):
4806
# Matplotlib relied on masked_invalid always returning a full mask
4807
# (Also astropy projects, but were ok with it gh-22720 and gh-22842)
4808
a = np.ma.array([1, 2, 3, 4])
4809
assert a._mask is nomask
4810
res = np.ma.masked_invalid(a, copy=copy)
4811
assert res.mask is not nomask
4812
# mask of a should not be mutated
4813
assert a.mask is nomask
4814
assert np.may_share_memory(a._data, res._data) != copy
4815
4816
def test_choose(self):
4817
# Test choose
4818
choices = [[0, 1, 2, 3], [10, 11, 12, 13],
4819
[20, 21, 22, 23], [30, 31, 32, 33]]
4820
chosen = choose([2, 3, 1, 0], choices)
4821
assert_equal(chosen, array([20, 31, 12, 3]))
4822
chosen = choose([2, 4, 1, 0], choices, mode='clip')
4823
assert_equal(chosen, array([20, 31, 12, 3]))
4824
chosen = choose([2, 4, 1, 0], choices, mode='wrap')
4825
assert_equal(chosen, array([20, 1, 12, 3]))
4826
# Check with some masked indices
4827
indices_ = array([2, 4, 1, 0], mask=[1, 0, 0, 1])
4828
chosen = choose(indices_, choices, mode='wrap')
4829
assert_equal(chosen, array([99, 1, 12, 99]))
4830
assert_equal(chosen.mask, [1, 0, 0, 1])
4831
# Check with some masked choices
4832
choices = array(choices, mask=[[0, 0, 0, 1], [1, 1, 0, 1],
4833
[1, 0, 0, 0], [0, 0, 0, 0]])
4834
indices_ = [2, 3, 1, 0]
4835
chosen = choose(indices_, choices, mode='wrap')
4836
assert_equal(chosen, array([20, 31, 12, 3]))
4837
assert_equal(chosen.mask, [1, 0, 0, 1])
4838
4839
def test_choose_with_out(self):
4840
# Test choose with an explicit out keyword
4841
choices = [[0, 1, 2, 3], [10, 11, 12, 13],
4842
[20, 21, 22, 23], [30, 31, 32, 33]]
4843
store = empty(4, dtype=int)
4844
chosen = choose([2, 3, 1, 0], choices, out=store)
4845
assert_equal(store, array([20, 31, 12, 3]))
4846
assert_(store is chosen)
4847
# Check with some masked indices + out
4848
store = empty(4, dtype=int)
4849
indices_ = array([2, 3, 1, 0], mask=[1, 0, 0, 1])
4850
chosen = choose(indices_, choices, mode='wrap', out=store)
4851
assert_equal(store, array([99, 31, 12, 99]))
4852
assert_equal(store.mask, [1, 0, 0, 1])
4853
# Check with some masked choices + out ina ndarray !
4854
choices = array(choices, mask=[[0, 0, 0, 1], [1, 1, 0, 1],
4855
[1, 0, 0, 0], [0, 0, 0, 0]])
4856
indices_ = [2, 3, 1, 0]
4857
store = empty(4, dtype=int).view(ndarray)
4858
chosen = choose(indices_, choices, mode='wrap', out=store)
4859
assert_equal(store, array([999999, 31, 12, 999999]))
4860
4861
def test_reshape(self):
4862
a = arange(10)
4863
a[0] = masked
4864
# Try the default
4865
b = a.reshape((5, 2))
4866
assert_equal(b.shape, (5, 2))
4867
assert_(b.flags['C'])
4868
# Try w/ arguments as list instead of tuple
4869
b = a.reshape(5, 2)
4870
assert_equal(b.shape, (5, 2))
4871
assert_(b.flags['C'])
4872
# Try w/ order
4873
b = a.reshape((5, 2), order='F')
4874
assert_equal(b.shape, (5, 2))
4875
assert_(b.flags['F'])
4876
# Try w/ order
4877
b = a.reshape(5, 2, order='F')
4878
assert_equal(b.shape, (5, 2))
4879
assert_(b.flags['F'])
4880
4881
c = np.reshape(a, (2, 5))
4882
assert_(isinstance(c, MaskedArray))
4883
assert_equal(c.shape, (2, 5))
4884
assert_(c[0, 0] is masked)
4885
assert_(c.flags['C'])
4886
4887
def test_make_mask_descr(self):
4888
# Flexible
4889
ntype = [('a', float), ('b', float)]
4890
test = make_mask_descr(ntype)
4891
assert_equal(test, [('a', bool), ('b', bool)])
4892
assert_(test is make_mask_descr(test))
4893
4894
# Standard w/ shape
4895
ntype = (float, 2)
4896
test = make_mask_descr(ntype)
4897
assert_equal(test, (bool, 2))
4898
assert_(test is make_mask_descr(test))
4899
4900
# Standard standard
4901
ntype = float
4902
test = make_mask_descr(ntype)
4903
assert_equal(test, np.dtype(bool))
4904
assert_(test is make_mask_descr(test))
4905
4906
# Nested
4907
ntype = [('a', float), ('b', [('ba', float), ('bb', float)])]
4908
test = make_mask_descr(ntype)
4909
control = np.dtype([('a', 'b1'), ('b', [('ba', 'b1'), ('bb', 'b1')])])
4910
assert_equal(test, control)
4911
assert_(test is make_mask_descr(test))
4912
4913
# Named+ shape
4914
ntype = [('a', (float, 2))]
4915
test = make_mask_descr(ntype)
4916
assert_equal(test, np.dtype([('a', (bool, 2))]))
4917
assert_(test is make_mask_descr(test))
4918
4919
# 2 names
4920
ntype = [(('A', 'a'), float)]
4921
test = make_mask_descr(ntype)
4922
assert_equal(test, np.dtype([(('A', 'a'), bool)]))
4923
assert_(test is make_mask_descr(test))
4924
4925
# nested boolean types should preserve identity
4926
base_type = np.dtype([('a', int, 3)])
4927
base_mtype = make_mask_descr(base_type)
4928
sub_type = np.dtype([('a', int), ('b', base_mtype)])
4929
test = make_mask_descr(sub_type)
4930
assert_equal(test, np.dtype([('a', bool), ('b', [('a', bool, 3)])]))
4931
assert_(test.fields['b'][0] is base_mtype)
4932
4933
def test_make_mask(self):
4934
# Test make_mask
4935
# w/ a list as an input
4936
mask = [0, 1]
4937
test = make_mask(mask)
4938
assert_equal(test.dtype, MaskType)
4939
assert_equal(test, [0, 1])
4940
# w/ a ndarray as an input
4941
mask = np.array([0, 1], dtype=bool)
4942
test = make_mask(mask)
4943
assert_equal(test.dtype, MaskType)
4944
assert_equal(test, [0, 1])
4945
# w/ a flexible-type ndarray as an input - use default
4946
mdtype = [('a', bool), ('b', bool)]
4947
mask = np.array([(0, 0), (0, 1)], dtype=mdtype)
4948
test = make_mask(mask)
4949
assert_equal(test.dtype, MaskType)
4950
assert_equal(test, [1, 1])
4951
# w/ a flexible-type ndarray as an input - use input dtype
4952
mdtype = [('a', bool), ('b', bool)]
4953
mask = np.array([(0, 0), (0, 1)], dtype=mdtype)
4954
test = make_mask(mask, dtype=mask.dtype)
4955
assert_equal(test.dtype, mdtype)
4956
assert_equal(test, mask)
4957
# w/ a flexible-type ndarray as an input - use input dtype
4958
mdtype = [('a', float), ('b', float)]
4959
bdtype = [('a', bool), ('b', bool)]
4960
mask = np.array([(0, 0), (0, 1)], dtype=mdtype)
4961
test = make_mask(mask, dtype=mask.dtype)
4962
assert_equal(test.dtype, bdtype)
4963
assert_equal(test, np.array([(0, 0), (0, 1)], dtype=bdtype))
4964
# Ensure this also works for void
4965
mask = np.array((False, True), dtype='?,?')[()]
4966
assert_(isinstance(mask, np.void))
4967
test = make_mask(mask, dtype=mask.dtype)
4968
assert_equal(test, mask)
4969
assert_(test is not mask)
4970
mask = np.array((0, 1), dtype='i4,i4')[()]
4971
test2 = make_mask(mask, dtype=mask.dtype)
4972
assert_equal(test2, test)
4973
# test that nomask is returned when m is nomask.
4974
bools = [True, False]
4975
dtypes = [MaskType, float]
4976
msgformat = 'copy=%s, shrink=%s, dtype=%s'
4977
for cpy, shr, dt in itertools.product(bools, bools, dtypes):
4978
res = make_mask(nomask, copy=cpy, shrink=shr, dtype=dt)
4979
assert_(res is nomask, msgformat % (cpy, shr, dt))
4980
4981
def test_mask_or(self):
4982
# Initialize
4983
mtype = [('a', bool), ('b', bool)]
4984
mask = np.array([(0, 0), (0, 1), (1, 0), (0, 0)], dtype=mtype)
4985
# Test using nomask as input
4986
test = mask_or(mask, nomask)
4987
assert_equal(test, mask)
4988
test = mask_or(nomask, mask)
4989
assert_equal(test, mask)
4990
# Using False as input
4991
test = mask_or(mask, False)
4992
assert_equal(test, mask)
4993
# Using another array w / the same dtype
4994
other = np.array([(0, 1), (0, 1), (0, 1), (0, 1)], dtype=mtype)
4995
test = mask_or(mask, other)
4996
control = np.array([(0, 1), (0, 1), (1, 1), (0, 1)], dtype=mtype)
4997
assert_equal(test, control)
4998
# Using another array w / a different dtype
4999
othertype = [('A', bool), ('B', bool)]
5000
other = np.array([(0, 1), (0, 1), (0, 1), (0, 1)], dtype=othertype)
5001
try:
5002
test = mask_or(mask, other)
5003
except ValueError:
5004
pass
5005
# Using nested arrays
5006
dtype = [('a', bool), ('b', [('ba', bool), ('bb', bool)])]
5007
amask = np.array([(0, (1, 0)), (0, (1, 0))], dtype=dtype)
5008
bmask = np.array([(1, (0, 1)), (0, (0, 0))], dtype=dtype)
5009
cntrl = np.array([(1, (1, 1)), (0, (1, 0))], dtype=dtype)
5010
assert_equal(mask_or(amask, bmask), cntrl)
5011
5012
a = np.array([False, False])
5013
assert mask_or(a, a) is nomask # gh-27360
5014
5015
def test_allequal(self):
5016
x = array([1, 2, 3], mask=[0, 0, 0])
5017
y = array([1, 2, 3], mask=[1, 0, 0])
5018
z = array([[1, 2, 3], [4, 5, 6]], mask=[[0, 0, 0], [1, 1, 1]])
5019
5020
assert allequal(x, y)
5021
assert not allequal(x, y, fill_value=False)
5022
assert allequal(x, z)
5023
5024
# test allequal for the same input, with mask=nomask, this test is for
5025
# the scenario raised in https://github.com/numpy/numpy/issues/27201
5026
assert allequal(x, x)
5027
assert allequal(x, x, fill_value=False)
5028
5029
assert allequal(y, y)
5030
assert not allequal(y, y, fill_value=False)
5031
5032
def test_flatten_mask(self):
5033
# Tests flatten mask
5034
# Standard dtype
5035
mask = np.array([0, 0, 1], dtype=bool)
5036
assert_equal(flatten_mask(mask), mask)
5037
# Flexible dtype
5038
mask = np.array([(0, 0), (0, 1)], dtype=[('a', bool), ('b', bool)])
5039
test = flatten_mask(mask)
5040
control = np.array([0, 0, 0, 1], dtype=bool)
5041
assert_equal(test, control)
5042
5043
mdtype = [('a', bool), ('b', [('ba', bool), ('bb', bool)])]
5044
data = [(0, (0, 0)), (0, (0, 1))]
5045
mask = np.array(data, dtype=mdtype)
5046
test = flatten_mask(mask)
5047
control = np.array([0, 0, 0, 0, 0, 1], dtype=bool)
5048
assert_equal(test, control)
5049
5050
def test_on_ndarray(self):
5051
# Test functions on ndarrays
5052
a = np.array([1, 2, 3, 4])
5053
m = array(a, mask=False)
5054
test = anom(a)
5055
assert_equal(test, m.anom())
5056
test = reshape(a, (2, 2))
5057
assert_equal(test, m.reshape(2, 2))
5058
5059
def test_compress(self):
5060
# Test compress function on ndarray and masked array
5061
# Address Github #2495.
5062
arr = np.arange(8)
5063
arr.shape = 4, 2
5064
cond = np.array([True, False, True, True])
5065
control = arr[[0, 2, 3]]
5066
test = np.ma.compress(cond, arr, axis=0)
5067
assert_equal(test, control)
5068
marr = np.ma.array(arr)
5069
test = np.ma.compress(cond, marr, axis=0)
5070
assert_equal(test, control)
5071
5072
def test_compressed(self):
5073
# Test ma.compressed function.
5074
# Address gh-4026
5075
a = np.ma.array([1, 2])
5076
test = np.ma.compressed(a)
5077
assert_(type(test) is np.ndarray)
5078
5079
# Test case when input data is ndarray subclass
5080
class A(np.ndarray):
5081
pass
5082
5083
a = np.ma.array(A(shape=0))
5084
test = np.ma.compressed(a)
5085
assert_(type(test) is A)
5086
5087
# Test that compress flattens
5088
test = np.ma.compressed([[1], [2]])
5089
assert_equal(test.ndim, 1)
5090
test = np.ma.compressed([[[[[1]]]]])
5091
assert_equal(test.ndim, 1)
5092
5093
# Test case when input is MaskedArray subclass
5094
class M(MaskedArray):
5095
pass
5096
5097
test = np.ma.compressed(M([[[]], [[]]]))
5098
assert_equal(test.ndim, 1)
5099
5100
# with .compressed() overridden
5101
class M(MaskedArray):
5102
def compressed(self):
5103
return 42
5104
5105
test = np.ma.compressed(M([[[]], [[]]]))
5106
assert_equal(test, 42)
5107
5108
def test_convolve(self):
5109
a = masked_equal(np.arange(5), 2)
5110
b = np.array([1, 1])
5111
5112
result = masked_equal([0, 1, -1, -1, 7, 4], -1)
5113
test = np.ma.convolve(a, b, mode='full')
5114
assert_equal(test, result)
5115
5116
test = np.ma.convolve(a, b, mode='same')
5117
assert_equal(test, result[:-1])
5118
5119
test = np.ma.convolve(a, b, mode='valid')
5120
assert_equal(test, result[1:-1])
5121
5122
result = masked_equal([0, 1, 1, 3, 7, 4], -1)
5123
test = np.ma.convolve(a, b, mode='full', propagate_mask=False)
5124
assert_equal(test, result)
5125
5126
test = np.ma.convolve(a, b, mode='same', propagate_mask=False)
5127
assert_equal(test, result[:-1])
5128
5129
test = np.ma.convolve(a, b, mode='valid', propagate_mask=False)
5130
assert_equal(test, result[1:-1])
5131
5132
test = np.ma.convolve([1, 1], [1, 1, 1])
5133
assert_equal(test, masked_equal([1, 2, 2, 1], -1))
5134
5135
a = [1, 1]
5136
b = masked_equal([1, -1, -1, 1], -1)
5137
test = np.ma.convolve(a, b, propagate_mask=False)
5138
assert_equal(test, masked_equal([1, 1, -1, 1, 1], -1))
5139
test = np.ma.convolve(a, b, propagate_mask=True)
5140
assert_equal(test, masked_equal([-1, -1, -1, -1, -1], -1))
5141
5142
5143
class TestMaskedFields:
5144
def _create_data(self):
5145
ilist = [1, 2, 3, 4, 5]
5146
flist = [1.1, 2.2, 3.3, 4.4, 5.5]
5147
slist = ['one', 'two', 'three', 'four', 'five']
5148
ddtype = [('a', int), ('b', float), ('c', '|S8')]
5149
mdtype = [('a', bool), ('b', bool), ('c', bool)]
5150
mask = [0, 1, 0, 0, 1]
5151
base = array(list(zip(ilist, flist, slist)), mask=mask, dtype=ddtype)
5152
return {"base": base, "mask": mask, "ddtype": ddtype, "mdtype": mdtype}
5153
5154
def test_set_records_masks(self):
5155
data = self._create_data()
5156
base = data['base']
5157
mdtype = data['mdtype']
5158
# Set w/ nomask or masked
5159
base.mask = nomask
5160
assert_equal_records(base._mask, np.zeros(base.shape, dtype=mdtype))
5161
base.mask = masked
5162
assert_equal_records(base._mask, np.ones(base.shape, dtype=mdtype))
5163
# Set w/ simple boolean
5164
base.mask = False
5165
assert_equal_records(base._mask, np.zeros(base.shape, dtype=mdtype))
5166
base.mask = True
5167
assert_equal_records(base._mask, np.ones(base.shape, dtype=mdtype))
5168
# Set w/ list
5169
base.mask = [0, 0, 0, 1, 1]
5170
assert_equal_records(base._mask,
5171
np.array([(x, x, x) for x in [0, 0, 0, 1, 1]],
5172
dtype=mdtype))
5173
5174
def test_set_record_element(self):
5175
# Check setting an element of a record)
5176
base = self._create_data()['base']
5177
(base_a, base_b, base_c) = (base['a'], base['b'], base['c'])
5178
base[0] = (pi, pi, 'pi')
5179
5180
assert_equal(base_a.dtype, int)
5181
assert_equal(base_a._data, [3, 2, 3, 4, 5])
5182
5183
assert_equal(base_b.dtype, float)
5184
assert_equal(base_b._data, [pi, 2.2, 3.3, 4.4, 5.5])
5185
5186
assert_equal(base_c.dtype, '|S8')
5187
assert_equal(base_c._data,
5188
[b'pi', b'two', b'three', b'four', b'five'])
5189
5190
def test_set_record_slice(self):
5191
base = self._create_data()['base']
5192
(base_a, base_b, base_c) = (base['a'], base['b'], base['c'])
5193
base[:3] = (pi, pi, 'pi')
5194
5195
assert_equal(base_a.dtype, int)
5196
assert_equal(base_a._data, [3, 3, 3, 4, 5])
5197
5198
assert_equal(base_b.dtype, float)
5199
assert_equal(base_b._data, [pi, pi, pi, 4.4, 5.5])
5200
5201
assert_equal(base_c.dtype, '|S8')
5202
assert_equal(base_c._data,
5203
[b'pi', b'pi', b'pi', b'four', b'five'])
5204
5205
def test_mask_element(self):
5206
"Check record access"
5207
base = self._create_data()['base']
5208
base[0] = masked
5209
5210
for n in ('a', 'b', 'c'):
5211
assert_equal(base[n].mask, [1, 1, 0, 0, 1])
5212
assert_equal(base[n]._data, base._data[n])
5213
5214
def test_getmaskarray(self):
5215
# Test getmaskarray on flexible dtype
5216
ndtype = [('a', int), ('b', float)]
5217
test = empty(3, dtype=ndtype)
5218
assert_equal(getmaskarray(test),
5219
np.array([(0, 0), (0, 0), (0, 0)],
5220
dtype=[('a', '|b1'), ('b', '|b1')]))
5221
test[:] = masked
5222
assert_equal(getmaskarray(test),
5223
np.array([(1, 1), (1, 1), (1, 1)],
5224
dtype=[('a', '|b1'), ('b', '|b1')]))
5225
5226
def test_view(self):
5227
# Test view w/ flexible dtype
5228
iterator = list(zip(np.arange(10), np.random.rand(10)))
5229
data = np.array(iterator)
5230
a = array(iterator, dtype=[('a', float), ('b', float)])
5231
a.mask[0] = (1, 0)
5232
controlmask = np.array([1] + 19 * [0], dtype=bool)
5233
# Transform globally to simple dtype
5234
test = a.view(float)
5235
assert_equal(test, data.ravel())
5236
assert_equal(test.mask, controlmask)
5237
# Transform globally to dty
5238
test = a.view((float, 2))
5239
assert_equal(test, data)
5240
assert_equal(test.mask, controlmask.reshape(-1, 2))
5241
5242
def test_getitem(self):
5243
ndtype = [('a', float), ('b', float)]
5244
a = array(list(zip(np.random.rand(10), np.arange(10))), dtype=ndtype)
5245
a.mask = np.array(list(zip([0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
5246
[1, 0, 0, 0, 0, 0, 0, 0, 1, 0])),
5247
dtype=[('a', bool), ('b', bool)])
5248
5249
def _test_index(i):
5250
assert_equal(type(a[i]), mvoid)
5251
assert_equal_records(a[i]._data, a._data[i])
5252
assert_equal_records(a[i]._mask, a._mask[i])
5253
5254
assert_equal(type(a[i, ...]), MaskedArray)
5255
assert_equal_records(a[i, ...]._data, a._data[i, ...])
5256
assert_equal_records(a[i, ...]._mask, a._mask[i, ...])
5257
5258
_test_index(1) # No mask
5259
_test_index(0) # One element masked
5260
_test_index(-2) # All element masked
5261
5262
def test_setitem(self):
5263
# Issue 4866: check that one can set individual items in [record][col]
5264
# and [col][record] order
5265
ndtype = np.dtype([('a', float), ('b', int)])
5266
ma = np.ma.MaskedArray([(1.0, 1), (2.0, 2)], dtype=ndtype)
5267
ma['a'][1] = 3.0
5268
assert_equal(ma['a'], np.array([1.0, 3.0]))
5269
ma[1]['a'] = 4.0
5270
assert_equal(ma['a'], np.array([1.0, 4.0]))
5271
# Issue 2403
5272
mdtype = np.dtype([('a', bool), ('b', bool)])
5273
# soft mask
5274
control = np.array([(False, True), (True, True)], dtype=mdtype)
5275
a = np.ma.masked_all((2,), dtype=ndtype)
5276
a['a'][0] = 2
5277
assert_equal(a.mask, control)
5278
a = np.ma.masked_all((2,), dtype=ndtype)
5279
a[0]['a'] = 2
5280
assert_equal(a.mask, control)
5281
# hard mask
5282
control = np.array([(True, True), (True, True)], dtype=mdtype)
5283
a = np.ma.masked_all((2,), dtype=ndtype)
5284
a.harden_mask()
5285
a['a'][0] = 2
5286
assert_equal(a.mask, control)
5287
a = np.ma.masked_all((2,), dtype=ndtype)
5288
a.harden_mask()
5289
a[0]['a'] = 2
5290
assert_equal(a.mask, control)
5291
5292
def test_setitem_scalar(self):
5293
# 8510
5294
mask_0d = np.ma.masked_array(1, mask=True)
5295
arr = np.ma.arange(3)
5296
arr[0] = mask_0d
5297
assert_array_equal(arr.mask, [True, False, False])
5298
5299
def test_element_len(self):
5300
data = self._create_data()
5301
# check that len() works for mvoid (Github issue #576)
5302
for rec in data['base']:
5303
assert_equal(len(rec), len(data['ddtype']))
5304
5305
5306
class TestMaskedObjectArray:
5307
5308
def test_getitem(self):
5309
arr = np.ma.array([None, None])
5310
for dt in [float, object]:
5311
a0 = np.eye(2).astype(dt)
5312
a1 = np.eye(3).astype(dt)
5313
arr[0] = a0
5314
arr[1] = a1
5315
5316
assert_(arr[0] is a0)
5317
assert_(arr[1] is a1)
5318
assert_(isinstance(arr[0, ...], MaskedArray))
5319
assert_(isinstance(arr[1, ...], MaskedArray))
5320
assert_(arr[0, ...][()] is a0)
5321
assert_(arr[1, ...][()] is a1)
5322
5323
arr[0] = np.ma.masked
5324
5325
assert_(arr[1] is a1)
5326
assert_(isinstance(arr[0, ...], MaskedArray))
5327
assert_(isinstance(arr[1, ...], MaskedArray))
5328
assert_equal(arr[0, ...].mask, True)
5329
assert_(arr[1, ...][()] is a1)
5330
5331
# gh-5962 - object arrays of arrays do something special
5332
assert_equal(arr[0].data, a0)
5333
assert_equal(arr[0].mask, True)
5334
assert_equal(arr[0, ...][()].data, a0)
5335
assert_equal(arr[0, ...][()].mask, True)
5336
5337
def test_nested_ma(self):
5338
5339
arr = np.ma.array([None, None])
5340
# set the first object to be an unmasked masked constant. A little fiddly
5341
arr[0, ...] = np.array([np.ma.masked], object)[0, ...]
5342
5343
# check the above line did what we were aiming for
5344
assert_(arr.data[0] is np.ma.masked)
5345
5346
# test that getitem returned the value by identity
5347
assert_(arr[0] is np.ma.masked)
5348
5349
# now mask the masked value!
5350
arr[0] = np.ma.masked
5351
assert_(arr[0] is np.ma.masked)
5352
5353
5354
class TestMaskedView:
5355
def _create_data(self):
5356
iterator = list(zip(np.arange(10), np.random.rand(10)))
5357
data = np.array(iterator)
5358
a = array(iterator, dtype=[('a', float), ('b', float)])
5359
a.mask[0] = (1, 0)
5360
controlmask = np.array([1] + 19 * [0], dtype=bool)
5361
return data, a, controlmask
5362
5363
def test_view_to_nothing(self):
5364
a = self._create_data()[1]
5365
test = a.view()
5366
assert_(isinstance(test, MaskedArray))
5367
assert_equal(test._data, a._data)
5368
assert_equal(test._mask, a._mask)
5369
5370
def test_view_to_type(self):
5371
data, a, _ = self._create_data()
5372
test = a.view(np.ndarray)
5373
assert_(not isinstance(test, MaskedArray))
5374
assert_equal(test, a._data)
5375
assert_equal_records(test, data.view(a.dtype).squeeze())
5376
5377
def test_view_to_simple_dtype(self):
5378
data, a, controlmask = self._create_data()
5379
# View globally
5380
test = a.view(float)
5381
assert_(isinstance(test, MaskedArray))
5382
assert_equal(test, data.ravel())
5383
assert_equal(test.mask, controlmask)
5384
5385
def test_view_to_flexible_dtype(self):
5386
a = self._create_data()[1]
5387
5388
test = a.view([('A', float), ('B', float)])
5389
assert_equal(test.mask.dtype.names, ('A', 'B'))
5390
assert_equal(test['A'], a['a'])
5391
assert_equal(test['B'], a['b'])
5392
5393
test = a[0].view([('A', float), ('B', float)])
5394
assert_(isinstance(test, MaskedArray))
5395
assert_equal(test.mask.dtype.names, ('A', 'B'))
5396
assert_equal(test['A'], a['a'][0])
5397
assert_equal(test['B'], a['b'][0])
5398
5399
test = a[-1].view([('A', float), ('B', float)])
5400
assert_(isinstance(test, MaskedArray))
5401
assert_equal(test.dtype.names, ('A', 'B'))
5402
assert_equal(test['A'], a['a'][-1])
5403
assert_equal(test['B'], a['b'][-1])
5404
5405
def test_view_to_subdtype(self):
5406
data, a, controlmask = self._create_data()
5407
# View globally
5408
test = a.view((float, 2))
5409
assert_(isinstance(test, MaskedArray))
5410
assert_equal(test, data)
5411
assert_equal(test.mask, controlmask.reshape(-1, 2))
5412
# View on 1 masked element
5413
test = a[0].view((float, 2))
5414
assert_(isinstance(test, MaskedArray))
5415
assert_equal(test, data[0])
5416
assert_equal(test.mask, (1, 0))
5417
# View on 1 unmasked element
5418
test = a[-1].view((float, 2))
5419
assert_(isinstance(test, MaskedArray))
5420
assert_equal(test, data[-1])
5421
5422
def test_view_to_dtype_and_type(self):
5423
data, a, _ = self._create_data()
5424
5425
test = a.view((float, 2), np.recarray)
5426
assert_equal(test, data)
5427
assert_(isinstance(test, np.recarray))
5428
assert_(not isinstance(test, MaskedArray))
5429
5430
5431
class TestOptionalArgs:
5432
def test_ndarrayfuncs(self):
5433
# test axis arg behaves the same as ndarray (including multiple axes)
5434
5435
d = np.arange(24.0).reshape((2, 3, 4))
5436
m = np.zeros(24, dtype=bool).reshape((2, 3, 4))
5437
# mask out last element of last dimension
5438
m[:, :, -1] = True
5439
a = np.ma.array(d, mask=m)
5440
5441
def testaxis(f, a, d):
5442
numpy_f = numpy.__getattribute__(f)
5443
ma_f = np.ma.__getattribute__(f)
5444
5445
# test axis arg
5446
assert_equal(ma_f(a, axis=1)[..., :-1], numpy_f(d[..., :-1], axis=1))
5447
assert_equal(ma_f(a, axis=(0, 1))[..., :-1],
5448
numpy_f(d[..., :-1], axis=(0, 1)))
5449
5450
def testkeepdims(f, a, d):
5451
numpy_f = numpy.__getattribute__(f)
5452
ma_f = np.ma.__getattribute__(f)
5453
5454
# test keepdims arg
5455
assert_equal(ma_f(a, keepdims=True).shape,
5456
numpy_f(d, keepdims=True).shape)
5457
assert_equal(ma_f(a, keepdims=False).shape,
5458
numpy_f(d, keepdims=False).shape)
5459
5460
# test both at once
5461
assert_equal(ma_f(a, axis=1, keepdims=True)[..., :-1],
5462
numpy_f(d[..., :-1], axis=1, keepdims=True))
5463
assert_equal(ma_f(a, axis=(0, 1), keepdims=True)[..., :-1],
5464
numpy_f(d[..., :-1], axis=(0, 1), keepdims=True))
5465
5466
for f in ['sum', 'prod', 'mean', 'var', 'std']:
5467
testaxis(f, a, d)
5468
testkeepdims(f, a, d)
5469
5470
for f in ['min', 'max']:
5471
testaxis(f, a, d)
5472
5473
d = (np.arange(24).reshape((2, 3, 4)) % 2 == 0)
5474
a = np.ma.array(d, mask=m)
5475
for f in ['all', 'any']:
5476
testaxis(f, a, d)
5477
testkeepdims(f, a, d)
5478
5479
def test_count(self):
5480
# test np.ma.count specially
5481
5482
d = np.arange(24.0).reshape((2, 3, 4))
5483
m = np.zeros(24, dtype=bool).reshape((2, 3, 4))
5484
m[:, 0, :] = True
5485
a = np.ma.array(d, mask=m)
5486
5487
assert_equal(count(a), 16)
5488
assert_equal(count(a, axis=1), 2 * ones((2, 4)))
5489
assert_equal(count(a, axis=(0, 1)), 4 * ones((4,)))
5490
assert_equal(count(a, keepdims=True), 16 * ones((1, 1, 1)))
5491
assert_equal(count(a, axis=1, keepdims=True), 2 * ones((2, 1, 4)))
5492
assert_equal(count(a, axis=(0, 1), keepdims=True), 4 * ones((1, 1, 4)))
5493
assert_equal(count(a, axis=-2), 2 * ones((2, 4)))
5494
assert_raises(ValueError, count, a, axis=(1, 1))
5495
assert_raises(AxisError, count, a, axis=3)
5496
5497
# check the 'nomask' path
5498
a = np.ma.array(d, mask=nomask)
5499
5500
assert_equal(count(a), 24)
5501
assert_equal(count(a, axis=1), 3 * ones((2, 4)))
5502
assert_equal(count(a, axis=(0, 1)), 6 * ones((4,)))
5503
assert_equal(count(a, keepdims=True), 24 * ones((1, 1, 1)))
5504
assert_equal(np.ndim(count(a, keepdims=True)), 3)
5505
assert_equal(count(a, axis=1, keepdims=True), 3 * ones((2, 1, 4)))
5506
assert_equal(count(a, axis=(0, 1), keepdims=True), 6 * ones((1, 1, 4)))
5507
assert_equal(count(a, axis=-2), 3 * ones((2, 4)))
5508
assert_raises(ValueError, count, a, axis=(1, 1))
5509
assert_raises(AxisError, count, a, axis=3)
5510
5511
# check the 'masked' singleton
5512
assert_equal(count(np.ma.masked), 0)
5513
5514
# check 0-d arrays do not allow axis > 0
5515
assert_raises(AxisError, count, np.ma.array(1), axis=1)
5516
5517
5518
class TestMaskedConstant:
5519
def _do_add_test(self, add):
5520
# sanity check
5521
assert_(add(np.ma.masked, 1) is np.ma.masked)
5522
5523
# now try with a vector
5524
vector = np.array([1, 2, 3])
5525
result = add(np.ma.masked, vector)
5526
5527
# lots of things could go wrong here
5528
assert_(result is not np.ma.masked)
5529
assert_(not isinstance(result, np.ma.core.MaskedConstant))
5530
assert_equal(result.shape, vector.shape)
5531
assert_equal(np.ma.getmask(result), np.ones(vector.shape, dtype=bool))
5532
5533
def test_ufunc(self):
5534
self._do_add_test(np.add)
5535
5536
def test_operator(self):
5537
self._do_add_test(lambda a, b: a + b)
5538
5539
def test_ctor(self):
5540
m = np.ma.array(np.ma.masked)
5541
5542
# most importantly, we do not want to create a new MaskedConstant
5543
# instance
5544
assert_(not isinstance(m, np.ma.core.MaskedConstant))
5545
assert_(m is not np.ma.masked)
5546
5547
def test_repr(self):
5548
# copies should not exist, but if they do, it should be obvious that
5549
# something is wrong
5550
assert_equal(repr(np.ma.masked), 'masked')
5551
5552
# create a new instance in a weird way
5553
masked2 = np.ma.MaskedArray.__new__(np.ma.core.MaskedConstant)
5554
assert_not_equal(repr(masked2), 'masked')
5555
5556
def test_pickle(self):
5557
from io import BytesIO
5558
5559
for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
5560
with BytesIO() as f:
5561
pickle.dump(np.ma.masked, f, protocol=proto)
5562
f.seek(0)
5563
res = pickle.load(f)
5564
assert_(res is np.ma.masked)
5565
5566
def test_copy(self):
5567
# gh-9328
5568
# copy is a no-op, like it is with np.True_
5569
assert_equal(
5570
np.ma.masked.copy() is np.ma.masked,
5571
np.True_.copy() is np.True_)
5572
5573
def test__copy(self):
5574
import copy
5575
assert_(
5576
copy.copy(np.ma.masked) is np.ma.masked)
5577
5578
def test_deepcopy(self):
5579
import copy
5580
assert_(
5581
copy.deepcopy(np.ma.masked) is np.ma.masked)
5582
5583
def test_immutable(self):
5584
orig = np.ma.masked
5585
assert_raises(np.ma.core.MaskError, operator.setitem, orig, (), 1)
5586
assert_raises(ValueError, operator.setitem, orig.data, (), 1)
5587
assert_raises(ValueError, operator.setitem, orig.mask, (), False)
5588
5589
view = np.ma.masked.view(np.ma.MaskedArray)
5590
assert_raises(ValueError, operator.setitem, view, (), 1)
5591
assert_raises(ValueError, operator.setitem, view.data, (), 1)
5592
assert_raises(ValueError, operator.setitem, view.mask, (), False)
5593
5594
def test_coercion_int(self):
5595
a_i = np.zeros((), int)
5596
assert_raises(MaskError, operator.setitem, a_i, (), np.ma.masked)
5597
assert_raises(MaskError, int, np.ma.masked)
5598
5599
def test_coercion_float(self):
5600
a_f = np.zeros((), float)
5601
pytest.warns(UserWarning, operator.setitem, a_f, (), np.ma.masked)
5602
assert_(np.isnan(a_f[()]))
5603
5604
@pytest.mark.xfail(reason="See gh-9750")
5605
def test_coercion_unicode(self):
5606
a_u = np.zeros((), 'U10')
5607
a_u[()] = np.ma.masked
5608
assert_equal(a_u[()], '--')
5609
5610
@pytest.mark.xfail(reason="See gh-9750")
5611
def test_coercion_bytes(self):
5612
a_b = np.zeros((), 'S10')
5613
a_b[()] = np.ma.masked
5614
assert_equal(a_b[()], b'--')
5615
5616
def test_subclass(self):
5617
# https://github.com/astropy/astropy/issues/6645
5618
class Sub(type(np.ma.masked)):
5619
pass
5620
5621
a = Sub()
5622
assert_(a is Sub())
5623
assert_(a is not np.ma.masked)
5624
assert_not_equal(repr(a), 'masked')
5625
5626
def test_attributes_readonly(self):
5627
assert_raises(AttributeError, setattr, np.ma.masked, 'shape', (1,))
5628
assert_raises(AttributeError, setattr, np.ma.masked, 'dtype', np.int64)
5629
5630
5631
class TestMaskedWhereAliases:
5632
5633
# TODO: Test masked_object, masked_equal, ...
5634
5635
def test_masked_values(self):
5636
res = masked_values(np.array([-32768.0]), np.int16(-32768))
5637
assert_equal(res.mask, [True])
5638
5639
res = masked_values(np.inf, np.inf)
5640
assert_equal(res.mask, True)
5641
5642
res = np.ma.masked_values(np.inf, -np.inf)
5643
assert_equal(res.mask, False)
5644
5645
res = np.ma.masked_values([1, 2, 3, 4], 5, shrink=True)
5646
assert_(res.mask is np.ma.nomask)
5647
5648
res = np.ma.masked_values([1, 2, 3, 4], 5, shrink=False)
5649
assert_equal(res.mask, [False] * 4)
5650
5651
5652
def test_masked_array():
5653
a = np.ma.array([0, 1, 2, 3], mask=[0, 0, 1, 0])
5654
assert_equal(np.argwhere(a), [[1], [3]])
5655
5656
5657
def test_masked_array_no_copy():
5658
# check nomask array is updated in place
5659
a = np.ma.array([1, 2, 3, 4])
5660
_ = np.ma.masked_where(a == 3, a, copy=False)
5661
assert_array_equal(a.mask, [False, False, True, False])
5662
# check masked array is updated in place
5663
a = np.ma.array([1, 2, 3, 4], mask=[1, 0, 0, 0])
5664
_ = np.ma.masked_where(a == 3, a, copy=False)
5665
assert_array_equal(a.mask, [True, False, True, False])
5666
# check masked array with masked_invalid is updated in place
5667
a = np.ma.array([np.inf, 1, 2, 3, 4])
5668
_ = np.ma.masked_invalid(a, copy=False)
5669
assert_array_equal(a.mask, [True, False, False, False, False])
5670
5671
5672
def test_append_masked_array():
5673
a = np.ma.masked_equal([1, 2, 3], value=2)
5674
b = np.ma.masked_equal([4, 3, 2], value=2)
5675
5676
result = np.ma.append(a, b)
5677
expected_data = [1, 2, 3, 4, 3, 2]
5678
expected_mask = [False, True, False, False, False, True]
5679
assert_array_equal(result.data, expected_data)
5680
assert_array_equal(result.mask, expected_mask)
5681
5682
a = np.ma.masked_all((2, 2))
5683
b = np.ma.ones((3, 1))
5684
5685
result = np.ma.append(a, b)
5686
expected_data = [1] * 3
5687
expected_mask = [True] * 4 + [False] * 3
5688
assert_array_equal(result.data[-3], expected_data)
5689
assert_array_equal(result.mask, expected_mask)
5690
5691
result = np.ma.append(a, b, axis=None)
5692
assert_array_equal(result.data[-3], expected_data)
5693
assert_array_equal(result.mask, expected_mask)
5694
5695
5696
def test_append_masked_array_along_axis():
5697
a = np.ma.masked_equal([1, 2, 3], value=2)
5698
b = np.ma.masked_values([[4, 5, 6], [7, 8, 9]], 7)
5699
5700
# When `axis` is specified, `values` must have the correct shape.
5701
assert_raises(ValueError, np.ma.append, a, b, axis=0)
5702
5703
result = np.ma.append(a[np.newaxis, :], b, axis=0)
5704
expected = np.ma.arange(1, 10)
5705
expected[[1, 6]] = np.ma.masked
5706
expected = expected.reshape((3, 3))
5707
assert_array_equal(result.data, expected.data)
5708
assert_array_equal(result.mask, expected.mask)
5709
5710
5711
def test_default_fill_value_complex():
5712
# regression test for Python 3, where 'unicode' was not defined
5713
assert_(default_fill_value(1 + 1j) == 1.e20 + 0.0j)
5714
5715
5716
def test_string_dtype_fill_value_on_construction():
5717
# Regression test for gh-29421: allow string fill_value on StringDType masked arrays
5718
dt = np.dtypes.StringDType()
5719
data = np.array(["A", "test", "variable", ""], dtype=dt)
5720
mask = [True, False, True, True]
5721
# Prior to the fix, this would TypeError; now it should succeed
5722
arr = np.ma.MaskedArray(data, mask=mask, fill_value="FILL", dtype=dt)
5723
assert isinstance(arr.fill_value, str)
5724
assert arr.fill_value == "FILL"
5725
filled = arr.filled()
5726
# Masked positions should be replaced by 'FILL'
5727
assert filled.tolist() == ["FILL", "test", "FILL", "FILL"]
5728
5729
5730
def test_string_dtype_default_fill_value():
5731
# Regression test for gh-29421: default fill_value for StringDType is 'N/A'
5732
dt = np.dtypes.StringDType()
5733
data = np.array(['x', 'y', 'z'], dtype=dt)
5734
# no fill_value passed → uses default_fill_value internally
5735
arr = np.ma.MaskedArray(data, mask=[True, False, True], dtype=dt)
5736
# ensure it’s stored as a Python str and equals the expected default
5737
assert isinstance(arr.fill_value, str)
5738
assert arr.fill_value == 'N/A'
5739
# masked slots should be replaced by that default
5740
assert arr.filled().tolist() == ['N/A', 'y', 'N/A']
5741
5742
5743
def test_string_dtype_fill_value_persists_through_slice():
5744
# Regression test for gh-29421: .fill_value survives slicing/viewing
5745
dt = np.dtypes.StringDType()
5746
arr = np.ma.MaskedArray(
5747
['a', 'b', 'c'],
5748
mask=[True, False, True],
5749
dtype=dt
5750
)
5751
arr.fill_value = 'Z'
5752
# slice triggers __array_finalize__
5753
sub = arr[1:]
5754
# the slice should carry the same fill_value and behavior
5755
assert isinstance(sub.fill_value, str)
5756
assert sub.fill_value == 'Z'
5757
assert sub.filled().tolist() == ['b', 'Z']
5758
5759
5760
def test_setting_fill_value_attribute():
5761
# Regression test for gh-29421: setting .fill_value post-construction works too
5762
dt = np.dtypes.StringDType()
5763
arr = np.ma.MaskedArray(
5764
["x", "longstring", "mid"], mask=[False, True, False], dtype=dt
5765
)
5766
# Setting the attribute should not raise
5767
arr.fill_value = "Z"
5768
assert arr.fill_value == "Z"
5769
# And filled() should use the new fill_value
5770
assert arr.filled()[0] == "x"
5771
assert arr.filled()[1] == "Z"
5772
assert arr.filled()[2] == "mid"
5773
5774
5775
def test_ufunc_with_output():
5776
# check that giving an output argument always returns that output.
5777
# Regression test for gh-8416.
5778
x = array([1., 2., 3.], mask=[0, 0, 1])
5779
y = np.add(x, 1., out=x)
5780
assert_(y is x)
5781
5782
5783
def test_ufunc_with_out_varied():
5784
""" Test that masked arrays are immune to gh-10459 """
5785
# the mask of the output should not affect the result, however it is passed
5786
a = array([ 1, 2, 3], mask=[1, 0, 0])
5787
b = array([10, 20, 30], mask=[1, 0, 0])
5788
out = array([ 0, 0, 0], mask=[0, 0, 1])
5789
expected = array([11, 22, 33], mask=[1, 0, 0])
5790
5791
out_pos = out.copy()
5792
res_pos = np.add(a, b, out_pos)
5793
5794
out_kw = out.copy()
5795
res_kw = np.add(a, b, out=out_kw)
5796
5797
out_tup = out.copy()
5798
res_tup = np.add(a, b, out=(out_tup,))
5799
5800
assert_equal(res_kw.mask, expected.mask)
5801
assert_equal(res_kw.data, expected.data)
5802
assert_equal(res_tup.mask, expected.mask)
5803
assert_equal(res_tup.data, expected.data)
5804
assert_equal(res_pos.mask, expected.mask)
5805
assert_equal(res_pos.data, expected.data)
5806
5807
5808
def test_astype_mask_ordering():
5809
descr = np.dtype([('v', int, 3), ('x', [('y', float)])])
5810
x = array([
5811
[([1, 2, 3], (1.0,)), ([1, 2, 3], (2.0,))],
5812
[([1, 2, 3], (3.0,)), ([1, 2, 3], (4.0,))]], dtype=descr)
5813
x[0]['v'][0] = np.ma.masked
5814
5815
x_a = x.astype(descr)
5816
assert x_a.dtype.names == np.dtype(descr).names
5817
assert x_a.mask.dtype.names == np.dtype(descr).names
5818
assert_equal(x, x_a)
5819
5820
assert_(x is x.astype(x.dtype, copy=False))
5821
assert_equal(type(x.astype(x.dtype, subok=False)), np.ndarray)
5822
5823
x_f = x.astype(x.dtype, order='F')
5824
assert_(x_f.flags.f_contiguous)
5825
assert_(x_f.mask.flags.f_contiguous)
5826
5827
# Also test the same indirectly, via np.array
5828
x_a2 = np.array(x, dtype=descr, subok=True)
5829
assert x_a2.dtype.names == np.dtype(descr).names
5830
assert x_a2.mask.dtype.names == np.dtype(descr).names
5831
assert_equal(x, x_a2)
5832
5833
assert_(x is np.array(x, dtype=descr, copy=None, subok=True))
5834
5835
x_f2 = np.array(x, dtype=x.dtype, order='F', subok=True)
5836
assert_(x_f2.flags.f_contiguous)
5837
assert_(x_f2.mask.flags.f_contiguous)
5838
5839
5840
@pytest.mark.parametrize('dt1', num_dts, ids=num_ids)
5841
@pytest.mark.parametrize('dt2', num_dts, ids=num_ids)
5842
@pytest.mark.filterwarnings('ignore::numpy.exceptions.ComplexWarning')
5843
def test_astype_basic(dt1, dt2):
5844
# See gh-12070
5845
src = np.ma.array(ones(3, dt1), fill_value=1)
5846
dst = src.astype(dt2)
5847
5848
assert_(src.fill_value == 1)
5849
assert_(src.dtype == dt1)
5850
assert_(src.fill_value.dtype == dt1)
5851
5852
assert_(dst.fill_value == 1)
5853
assert_(dst.dtype == dt2)
5854
assert_(dst.fill_value.dtype == dt2)
5855
5856
assert_equal(src, dst)
5857
5858
5859
def test_fieldless_void():
5860
dt = np.dtype([]) # a void dtype with no fields
5861
x = np.empty(4, dt)
5862
5863
# these arrays contain no values, so there's little to test - but this
5864
# shouldn't crash
5865
mx = np.ma.array(x)
5866
assert_equal(mx.dtype, x.dtype)
5867
assert_equal(mx.shape, x.shape)
5868
5869
mx = np.ma.array(x, mask=x)
5870
assert_equal(mx.dtype, x.dtype)
5871
assert_equal(mx.shape, x.shape)
5872
5873
5874
def test_mask_shape_assignment_does_not_break_masked():
5875
a = np.ma.masked
5876
b = np.ma.array(1, mask=a.mask)
5877
b.shape = (1,)
5878
assert_equal(a.mask.shape, ())
5879
5880
5881
@pytest.mark.skipif(sys.flags.optimize > 1,
5882
reason="no docstrings present to inspect when PYTHONOPTIMIZE/Py_OptimizeFlag > 1") # noqa: E501
5883
def test_doc_note():
5884
def method(self):
5885
"""This docstring
5886
5887
Has multiple lines
5888
5889
And notes
5890
5891
Notes
5892
-----
5893
original note
5894
"""
5895
pass
5896
5897
expected_doc = """This docstring
5898
5899
Has multiple lines
5900
5901
And notes
5902
5903
Notes
5904
-----
5905
note
5906
5907
original note"""
5908
5909
assert_equal(np.ma.core.doc_note(method.__doc__, "note"), expected_doc)
5910
5911
5912
def test_gh_22556():
5913
source = np.ma.array([0, [0, 1, 2]], dtype=object)
5914
deepcopy = copy.deepcopy(source)
5915
deepcopy[1].append('this should not appear in source')
5916
assert len(source[1]) == 3
5917
5918
5919
def test_gh_21022():
5920
# testing for absence of reported error
5921
source = np.ma.masked_array(data=[-1, -1], mask=True, dtype=np.float64)
5922
axis = np.array(0)
5923
result = np.prod(source, axis=axis, keepdims=False)
5924
result = np.ma.masked_array(result,
5925
mask=np.ones(result.shape, dtype=np.bool))
5926
array = np.ma.masked_array(data=-1, mask=True, dtype=np.float64)
5927
copy.deepcopy(array)
5928
copy.deepcopy(result)
5929
5930
5931
def test_deepcopy_2d_obj():
5932
source = np.ma.array([[0, "dog"],
5933
[1, 1],
5934
[[1, 2], "cat"]],
5935
mask=[[0, 1],
5936
[0, 0],
5937
[0, 0]],
5938
dtype=object)
5939
deepcopy = copy.deepcopy(source)
5940
deepcopy[2, 0].extend(['this should not appear in source', 3])
5941
assert len(source[2, 0]) == 2
5942
assert len(deepcopy[2, 0]) == 4
5943
assert_equal(deepcopy._mask, source._mask)
5944
deepcopy._mask[0, 0] = 1
5945
assert source._mask[0, 0] == 0
5946
5947
5948
def test_deepcopy_0d_obj():
5949
source = np.ma.array(0, mask=[0], dtype=object)
5950
deepcopy = copy.deepcopy(source)
5951
deepcopy[...] = 17
5952
assert_equal(source, 0)
5953
assert_equal(deepcopy, 17)
5954
5955
5956
def test_uint_fill_value_and_filled():
5957
# See also gh-27269
5958
a = np.ma.MaskedArray([1, 1], [True, False], dtype="uint16")
5959
# the fill value should likely not be 99999, but for now guarantee it:
5960
assert a.fill_value == 999999
5961
# However, it's type is uint:
5962
assert a.fill_value.dtype.kind == "u"
5963
# And this ensures things like filled work:
5964
np.testing.assert_array_equal(
5965
a.filled(), np.array([999999, 1]).astype("uint16"), strict=True)
5966
5967