0

有很多与ValueErrors 相关的问题,其中不同形状的输入数组无法在 SO 在这里广播。但没有一个与面具有关:

ValueError could not broadcast where mask from shape (1) into shape ()

我正在做的是以下内容:

  • 遍历 NetCDF 4 文件(根组)中的所有变量
  • 将其内容从一个 NetCDF 文件复制到另一个新创建的文件中

原因与这个问题无关,但可以在这个问题中找到。

最小代码:

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[:]

这适用于所有变量的较新 Python(使用 >= 3.6 测试),但不适用于Python 2.7 †</sup> 用于未填充的标量 NetCDF 变量。在调试器中,就在引发此异常时,感兴趣的变量看起来像(在Python 2.7 和 3.6 中):

>>> variable.shape
()
>>> type(variable[:])
<class 'numpy.ma.core.MaskedConstant'>
>>> variable[:].mask
array(True, dtype=bool)
>>> variable[:]
masked
>>> print(variable[:])
--

所以这只发生在的标量 NetCDF 变量上。另一方面,将一个掩码常量分配给另一个掩码常量是可行的。只是里面的那个被屏蔽的常数。netCDF4._netCDF4.Variable为什么?以及如何解决?

编辑:numpy 1.7.1 和 netcdf4 1.2.7 发生故障。<- 这原来是问题的根源,请参阅此答案


variable是类型netCDF4._netCDF4.Variable,并且 print(dir(variable))显示['__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']


†</sup> 是的,我知道 Python 2 已停产。但它是必要的[插入来自遗留开发环境的原因]。

4

2 回答 2

2

如果文档是指您的相同版本,当shape是一个空元组时,您可以使用netCDF4.Variable.getValue()/netCDF4.Variable.assignValue()组合,例如:

if variable.shape:
    newVar[:] = variable[:]
else:
    newVar.assignValue(variable.getValue())

newVar[...] = variable[...],例如:

slicing = slice(None) if variable.shape else Ellipsis
newVar[slicing] = variable[slicing]
于 2020-06-25T13:46:00.643 回答
1

正如@norok2回答getValue()所揭示的那样,在这种情况下,在标量变量上使用或使用省略号切片都不起作用。ValueError两者都在 Python 2.7 的标量 NetCDF 变量上引发(出乎意料地)相同。然而,根据答案,推导出以下内容,通过不设置新创建的标量 NetCDF 变量来解决问题。

if isinstance(variable[:], numpy.ma.core.MaskedConstant):
    if variable[:].mask[()]:
        continue
newVar[:] = variable[:]

结果是正确的,因为只有当它是 a) 标量和 b) 掩码(variable未设置)时才会将原件复制到。newVar不复制意味着newVar保持未设置。这就像它被复制一样。


此问题似乎是特定于版本的。从 numpy 1.10.0 到 numpy 1.12.1,引发的异常更改为

IndexError: too many indices for array

从 numpy 1.13.0 开始,它运行良好。

这个GitHub 问题似乎是链接的。

于 2020-06-25T15:53:27.753 回答