There are a lot of questions related to ValueError
s where input arrays of different shape cannot be broadcast here at SO. But there are none are related to masks:
ValueError could not broadcast where mask from shape (1) into shape ()
What I'm doing is the following:
- go through all variables in (the root group of) a NetCDF 4 file
- copy their content from one NetCDF file into another, newly created one
The reason why is irrelevant for this question, but may be found in this question.
Minimal code:
with netCDF4.Dataset(inputFile) as src, \
netCDF4.Dataset(outputFile, "w") as dst:
# copy global attributes all at once via dictionary
dst.setncatts(ingroup.__dict__)
for variable in src.variables.values():
# create dimensions first
for dimName in variable.dimensions:
dst.createDimension(
dimName,
(len(dimension)
if not dimension.isunlimited() else None))
# now create variable
newVar = outgroup.createVariable(
variable.name,
variable.datatype,
variable.dimensions)
# copy variable attributes all at once via dictionary
newVar.setncatts(variable.__dict__)
# copy content
newVar[:] = variable[:]
This works on newer Pythons (tested with >= 3.6) for all variables, but does not with Python 2.7† for scalar NetCDF variables that are not filled. Within the debugger, right when this exception is raised, the variable of interest looks like (in both Python 2.7 and 3.6):
>>> variable.shape
()
>>> type(variable[:])
<class 'numpy.ma.core.MaskedConstant'>
>>> variable[:].mask
array(True, dtype=bool)
>>> variable[:]
masked
>>> print(variable[:])
--
So this only happens on empty scalar NetCDF variables. Assigning a masked constant to another masked constant on the other hand works. It's just that masked constant inside the netCDF4._netCDF4.Variable
.Why? And how to fix?
edit: failure occurs with numpy 1.7.1 and netcdf4 1.2.7. <- this turned out to be the source of the issue, see this answer.
variable
is of type netCDF4._netCDF4.Variable
, and
print(dir(variable))
shows ['__array__', '__class__', '__delattr__', '__delitem__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__len__', '__new__', '__orthogonal_indexing__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', '_assign_vlen', '_cmptype', '_enumtype', '_get', '_getdims', '_getname', '_grp', '_grpid', '_has_lsd', '_iscompound', '_isenum', '_isprimitive', '_isvlen', '_name', '_nunlimdim', '_put', '_toma', '_varid', '_vltype', 'assignValue', 'chunking', 'datatype', 'delncattr', 'dimensions', 'dtype', 'endian', 'filters', 'getValue', 'get_var_chunk_cache', 'getncattr', 'group', u'long_name', 'mask', 'name', 'ncattrs', 'ndim', 'renameAttribute', 'scale', 'set_auto_mask', 'set_auto_maskandscale', 'set_auto_scale', 'set_var_chunk_cache', 'setncattr', 'setncattr_string', 'setncatts', 'shape', 'size']
† Yes I know Python 2 is EOL. But it is needed for [insert reason from legacy dev environment].