Skip to content

Commit 0b6c6c9

Browse files
Fix as_compatible_data for read-only np.ma.MaskedArray (#7788)
* Fix as_compatible_data for non-writeable float MaskedArray * Add test for #2377 --------- Co-authored-by: dcherian <[email protected]>
1 parent c8c6a4b commit 0b6c6c9

File tree

3 files changed

+16
-2
lines changed

3 files changed

+16
-2
lines changed

doc/whats-new.rst

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ New Features
2727
- Add support for lshift and rshift binary operators (``<<``, ``>>``) on
2828
:py:class:`xr.DataArray` of type :py:class:`int` (:issue:`7727` , :pull:`7741`).
2929
By `Alan Brammer <https://github.com/abrammer>`_.
30+
- Fix `as_compatible_data` for masked float arrays, now always creates a copy when mask is present (:issue:`2377`, :pull:`7788`).
31+
By `Max Hollmann <https://github.com/maxhollmann>`_.
3032

3133

3234
Breaking changes

xarray/core/variable.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,7 @@ def as_compatible_data(data, fastpath=False):
274274
mask = np.ma.getmaskarray(data)
275275
if mask.any():
276276
dtype, fill_value = dtypes.maybe_promote(data.dtype)
277-
data = np.asarray(data, dtype=dtype)
278-
data[mask] = fill_value
277+
data = duck_array_ops.where_method(data, ~mask, fill_value)
279278
else:
280279
data = np.asarray(data)
281280

xarray/tests/test_variable.py

+13
Original file line numberDiff line numberDiff line change
@@ -2560,6 +2560,19 @@ def test_masked_array(self):
25602560
assert_array_equal(expected, actual)
25612561
assert np.dtype(float) == actual.dtype
25622562

2563+
original = np.ma.MaskedArray([1.0, 2.0], mask=[True, False])
2564+
original.flags.writeable = False
2565+
expected = [np.nan, 2.0]
2566+
actual = as_compatible_data(original)
2567+
assert_array_equal(expected, actual)
2568+
assert np.dtype(float) == actual.dtype
2569+
2570+
# GH2377
2571+
actual = Variable(dims=tuple(), data=np.ma.masked)
2572+
expected = Variable(dims=tuple(), data=np.nan)
2573+
assert_array_equal(expected, actual)
2574+
assert actual.dtype == expected.dtype
2575+
25632576
@pytest.mark.filterwarnings("ignore:Converting non-nanosecond")
25642577
def test_datetime(self):
25652578
expected = np.datetime64("2000-01-01")

0 commit comments

Comments
 (0)