Description
Describe the issue:
If a masked array of a structured void type with an array-valued field is built, the .fill_value
s differ between the following two cases (see the example):
- First accessing the array item (of
np.ma.core.mvoid
type), then accessing the array-valued field, and - First accessing the array-valued field (returning a masked array of scalar data type), then accessing the array item.
While both chains of item access result in a new masked array of the shape of the array-valued field, they have different .fill_value
s; the first form results in a .fill_value
which:
- Is array-valued, which does not seem consistent with masked arrays usually behaves, and
- Neglects the
.fill_value
of the parent array, substituting it with the default value for the data type as given by.get_fill_value()
.
Beside numpy 2.2
, the bug is also consistently reproduced in numpy 1.24
on my machine (MacOS 14.6.1 on M3 chip). Presumably, numpy
versions in between and before are also affected. Since this also has to do with .fill_value
inconsistencies on differing orders of operations, #22141 may be a related issue.
Reproduce the code example:
from numpy.ma import MaskedArray
# This masked array contains a structured void with a single field which is array-valued
ma = MaskedArray([((1,),)], dtype=[('a', 'i', (1,))], fill_value=-1)
# 1. Item access -> field access:
# `.fill_value` becomes an array and falls back to the default
subma_1 = ma[0]['a']
# >>> subma_1
# masked_array(data=[1],
# mask=[False],
# fill_value=[999999],
# dtype=int32)
assert subma_1.fill_value.shape == (1,)
assert subma_1.fill_value[0] != -1
# 2. Field access -> item access:
# `.fill_value` remains a scalar and retains the specified value
subma_2 = ma['a'][0]
# >>> subma_2
# masked_array(data=[1],
# mask=[False],
# fill_value=-1,
# dtype=int32)
assert subma_2.fill_value.shape == ()
assert subma_2.fill_value[0] == -1
Error message:
Python and NumPy Versions:
2.2.2
3.13.2 (main, Feb 4 2025, 14:51:09) [Clang 16.0.0 (clang-1600.0.26.6)]
Runtime Environment:
No response
Context for the issue:
It is understood that this is an edge case, and the .fill_value
is mostly not of concern to end-users. Still, it may be of use to document it here, and of interest in revealing other possible inconsistencies.