8000 BUG: `MaskedArray.fill_value` not consistently preserved in structured voids with array-valued fields · Issue #28450 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content
BUG: MaskedArray.fill_value not consistently preserved in structured voids with array-valued fields #28450
Open
@TTsangSC

Description

@TTsangSC

Describe the issue:

If a masked array of a structured void type with an array-valued field is built, the .fill_values differ between the following two cases (see the example):

  1. First accessing the array item (of np.ma.core.mvoid type), then accessing the array-valued field, and
  2. 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_values; 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0