summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorSebastian Berg <sebastianb@nvidia.com>2023-04-21 11:41:25 +0200
committerSebastian Berg <sebastianb@nvidia.com>2023-04-21 11:52:06 +0200
commit77a5aab54e10e063773e9aaf0e3730bf0cfefa9b (patch)
treed06bc9410741ca2dc24f4f07f6128286ee841187 /numpy
parente20f11036bb7ce9f8de91eb4240e49ea4e41ef17 (diff)
downloadnumpy-77a5aab54e10e063773e9aaf0e3730bf0cfefa9b.tar.gz
BUG: Fix masked array raveling when `order="A"` or `order="K"`
This transitively fixes gh-22912. I had alooked a bit into whether it is worthwhile to preserve the mask order, but TBH, we seem to not do so in so many places, that I don't think it really is worthwhile. Applying `order="K"` or `order="A"` to the data and mask separately is an big bug though. Closes gh-22912
Diffstat (limited to 'numpy')
-rw-r--r--numpy/ma/core.py8
-rw-r--r--numpy/ma/tests/test_core.py16
2 files changed, 24 insertions, 0 deletions
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index d2bd3d47e..077aaef1a 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -4631,6 +4631,7 @@ class MaskedArray(ndarray):
otherwise. 'K' means to read the elements in the order they occur
in memory, except for reversing the data when strides are negative.
By default, 'C' index order is used.
+ (Masked arrays currently use 'A' on the data when 'K' is passed.)
Returns
-------
@@ -4657,6 +4658,13 @@ class MaskedArray(ndarray):
fill_value=999999)
"""
+ # The order of _data and _mask could be different (it shouldn't be
+ # normally). Passing order `K` or `A` would be incorrect.
+ # So we ignore the mask memory order.
+ # TODO: We don't actually support K, so use A instead. We could
+ # try to guess this correct by sorting strides or deprecate.
+ if order in "kKaA":
+ order = "C" if self._data.flags.fnc else "F"
r = ndarray.ravel(self._data, order=order).view(type(self))
r._update_from(self)
if self._mask is not nomask:
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
index 5db01b74a..8fcd70c26 100644
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -3411,6 +3411,22 @@ class TestMaskedArrayMethods:
assert_equal(a.ravel(order='C'), [1, 2, 3, 4])
assert_equal(a.ravel(order='F'), [1, 3, 2, 4])
+ @pytest.mark.parametrize("order", "AKCF")
+ @pytest.mark.parametrize("data_order", "CF")
+ def test_ravel_order(self, order, data_order):
+ # Ravelling must ravel mask and data in the same order always to avoid
+ # misaligning the two in the ravel result.
+ arr = np.ones((5, 10), order=data_order)
+ arr[0, :] = 0
+ mask = np.ones((10, 5), dtype=bool, order=data_order).T
+ mask[0, :] = False
+ x = array(arr, mask=mask)
+ assert x._data.flags.fnc != x._mask.flags.fnc
+ assert (x.filled(0) == 0).all()
+ raveled = x.ravel(order)
+ assert (raveled.filled(0) == 0).all()
+
+
def test_reshape(self):
# Tests reshape
x = arange(4)