diff options
author | Eric Wieser <wieser.eric@gmail.com> | 2018-02-16 22:39:29 -0800 |
---|---|---|
committer | Eric Wieser <wieser.eric@gmail.com> | 2018-03-25 12:19:33 -0700 |
commit | 093c308fcc4249d8a0f1336827d8eb9ad1e7d274 (patch) | |
tree | ba3612fbbd3ea2890d2c8c231e244bf8928ba434 /numpy | |
parent | e2c71688e765a2c0eba4958891b0637754575f18 (diff) | |
download | python-numpy-093c308fcc4249d8a0f1336827d8eb9ad1e7d274.tar.gz python-numpy-093c308fcc4249d8a0f1336827d8eb9ad1e7d274.tar.bz2 python-numpy-093c308fcc4249d8a0f1336827d8eb9ad1e7d274.zip |
BUG: Always return a list from np.ma.flatnotmasked_contiguous
Depending on the input, this would return:
* A single slice, if mask=nomask
* A list of slices, if mask is an array
* None, if mask is fully masked
The documented return value is a list, and all downstream callers of this
function end up having to correct for it not being one.
This affects the result of np.ma.notmasked_contiguous, which also did not
document these unusual return values.
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/ma/extras.py | 50 | ||||
-rw-r--r-- | numpy/ma/tests/test_extras.py | 11 |
2 files changed, 44 insertions, 17 deletions
diff --git a/numpy/ma/extras.py b/numpy/ma/extras.py index e247fe170..8272dced9 100644 --- a/numpy/ma/extras.py +++ b/numpy/ma/extras.py @@ -1620,7 +1620,10 @@ def flatnotmasked_contiguous(a): Returns ------- slice_list : list - A sorted sequence of slices (start index, end index). + A sorted sequence of `slice` objects (start index, end index). + + ..versionchanged:: 1.15.0 + Now returns an empty list instead of None for a fully masked array See Also -------- @@ -1635,7 +1638,7 @@ def flatnotmasked_contiguous(a): -------- >>> a = np.ma.arange(10) >>> np.ma.flatnotmasked_contiguous(a) - slice(0, 10, None) + [slice(0, 10, None)] >>> mask = (a < 3) | (a > 8) | (a == 5) >>> a[mask] = np.ma.masked @@ -1645,13 +1648,13 @@ def flatnotmasked_contiguous(a): >>> np.ma.flatnotmasked_contiguous(a) [slice(3, 5, None), slice(6, 9, None)] >>> a[:] = np.ma.masked - >>> print(np.ma.flatnotmasked_edges(a)) - None + >>> np.ma.flatnotmasked_contiguous(a) + [] """ m = getmask(a) if m is nomask: - return slice(0, a.size, None) + return [slice(0, a.size)] i = 0 result = [] for (k, g) in itertools.groupby(m.ravel()): @@ -1659,7 +1662,7 @@ def flatnotmasked_contiguous(a): if not k: result.append(slice(i, i + n)) i += n - return result or None + return result def notmasked_contiguous(a, axis=None): """ @@ -1671,7 +1674,8 @@ def notmasked_contiguous(a, axis=None): The input array. axis : int, optional Axis along which to perform the operation. - If None (default), applies to a flattened version of the array. + If None (default), applies to a flattened version of the array, and this + is the same as `flatnotmasked_contiguous`. Returns ------- @@ -1679,6 +1683,8 @@ def notmasked_contiguous(a, axis=None): A list of slices (start and end indexes) of unmasked indexes in the array. + If the input is 2d and axis is specified, the result is a list of lists. + See Also -------- flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges, @@ -1690,17 +1696,35 @@ def notmasked_contiguous(a, axis=None): Examples -------- - >>> a = np.arange(9).reshape((3, 3)) + >>> a = np.arange(12).reshape((3, 4)) >>> mask = np.zeros_like(a) - >>> mask[1:, 1:] = 1 - + >>> mask[1:, :-1] = 1; mask[0, 1] = 1; mask[-1, 0] = 0 >>> ma = np.ma.array(a, mask=mask) + >>> ma + masked_array( + data=[[0, --, 2, 3], + [--, --, --, 7], + [8, --, --, 11]], + mask=[[False, True, False, False], + [ True, True, True, False], + [False, True, True, False]], + fill_value=999999) >>> np.array(ma[~ma.mask]) - array([0, 1, 2, 3, 6]) + array([ 0, 2, 3, 7, 8, 11]) >>> np.ma.notmasked_contiguous(ma) - [slice(0, 4, None), slice(6, 7, None)] + [slice(0, 1, None), slice(2, 4, None), slice(7, 9, None), slice(11, 12, None)] + + >>> np.ma.notmasked_contiguous(ma, axis=0) + [[slice(0, 1, None), slice(2, 3, None)], # column broken into two segments + [], # fully masked column + [slice(0, 1, None)], + [slice(0, 3, None)]] + >>> np.ma.notmasked_contiguous(ma, axis=1) + [[slice(0, 1, None), slice(2, 4, None)], # row broken into two segments + [slice(3, 4, None)], + [slice(0, 1, None), slice(3, 4, None)]] """ a = asarray(a) nd = a.ndim @@ -1717,7 +1741,7 @@ def notmasked_contiguous(a, axis=None): # for i in range(a.shape[other]): idx[other] = i - result.append(flatnotmasked_contiguous(a[tuple(idx)]) or None) + result.append(flatnotmasked_contiguous(a[tuple(idx)])) return result diff --git a/numpy/ma/tests/test_extras.py b/numpy/ma/tests/test_extras.py index 9bebd6145..95319eb65 100644 --- a/numpy/ma/tests/test_extras.py +++ b/numpy/ma/tests/test_extras.py @@ -128,7 +128,10 @@ class TestGeneric(object): a = arange(10) # No mask test = flatnotmasked_contiguous(a) - assert_equal(test, slice(0, a.size)) + assert_equal(test, [slice(0, a.size)]) + # mask of all false + a.mask = np.zeros(10, dtype=bool) + assert_equal(test, [slice(0, a.size)]) # Some mask a[(a < 3) | (a > 8) | (a == 5)] = masked test = flatnotmasked_contiguous(a) @@ -136,7 +139,7 @@ class TestGeneric(object): # a[:] = masked test = flatnotmasked_contiguous(a) - assert_equal(test, None) + assert_equal(test, []) class TestAverage(object): @@ -384,14 +387,14 @@ class TestNotMasked(object): [slice(0, 1, None), slice(2, 3, None)], [slice(2, 3, None)], [slice(2, 3, None)], - None, + [], [slice(2, 3, None)] ]) # tmp = notmasked_contiguous(a, 1) assert_equal(tmp, [ [slice(0, 4, None)], - None, + [], [slice(0, 6, None), slice(7, 8, None)] ]) |