如何解决numpy.ma.core.掩码错误:无法更改被屏蔽的元素?

omvjsjqw  于 2023-01-13  发布在  其他
关注(0)|答案(1)|浏览(237)

我是python的新手,我正在尝试将github(https://github.com/RDCEP/psims)上找到的python 2代码转换为python 3。转换进行得相当顺利,但现在我遇到了以下错误消息:

Traceback (most recent call last):

  File "jsons2dssat.py", line 1600, in run
    sfileoutput = SOLFileOutput(sfile, efile, use_ptransfer = pfcn)

  File "jsons2dssat.py", line 1336, in init
    if isMaskedArray(vl): vl[vl.mask] = -99

  File "/conda/pSIMS/lib/python3.7/site-packages/numpy/ma/core.py", line 3348, in setitem
raise MaskError('Cannot alter the masked element.')

numpy.ma.core.MaskError: Cannot alter the masked element.

--
在numpy.ma.core的源代码中,它是这样说的:

if self is masked:
        raise MaskError('Cannot alter the masked element.')

密码是

def __init__(self, soil_file, exp_file, use_ptransfer = True): # need experiment file to know which soil profiles to write
    # load soil data
    with nc(soil_file) as f:
        soil_vars   = setdiff1d(f.variables.keys(), f.dimensions.keys())
        soil_attrs  = f.ncattrs()
        soil_ids    = f.variables['soil_id'].long_name.split(', ')
        soil_depths = f.variables['depth'][:]

        nprofiles, ndepths = len(soil_ids), len(soil_depths)

        self.soils = []
        for i in range(nprofiles):
            self.soils.append({})

        for i in range(nprofiles):
            soil_layers = []
            for j in range(ndepths):
                soil_layers.append({})
                soil_layers[j]['sllb'] = str(soil_depths[j])

            for var in soil_attrs:
                self.soils[i][var] = f.getncattr(var)

            for var in soil_vars:
                v = f.variables[var]

                if 'profile' in v.dimensions and 'depth' in v.dimensions: # layer parameter
                    for j in range(ndepths):
                        vl = v[i, j, 0, 0]
                        if isMaskedArray(vl): vl[vl.mask] = -99

我知道为什么会出现这个错误,但是我不知道如何解决这个问题。我使用的是python 3.7和numpy版本1.24.1。任何帮助都非常感谢。谢谢!

eivgtgni

eivgtgni1#

我看到了

if self is masked:
    raise MaskError('Cannot alter the masked element.')

在我的setitem中。np.ma.masked是一个MaskedConstant(文档)
如果看起来像vl = v[i, j, 0, 0],则是数组v的元素(除非数组是5d)。
如果我做一个一维掩码数组,测试元素:

In [178]: m = np.ma.masked_array(np.arange(5.),[False, True,False,True,False])
In [179]: m
Out[179]: 
masked_array(data=[0.0, --, 2.0, --, 4.0],
             mask=[False,  True, False,  True, False],
       fill_value=1e+20)
In [180]: [m[i] is np.ma.masked for i in range(5)]
Out[180]: [False, True, False, True, False]

但是,如果我尝试更改某个值:输入[182]:m[1]输出[182]:在[183]中设盲:m[1]=-99英寸[184]:m输出[184]:掩码数组(数据=[0.0,-99.0,2.0,--,4.0],掩码=[假,假,假,真,假],填充值= 1 e +20)
请注意,m[1]不再被屏蔽。

In [185]: np.ma.isMaskedArray(m[1])
Out[185]: False
In [186]: np.ma.isMaskedArray(m[3])
Out[186]: True

现在,如果我们不执行m[3]=-99,而是将m[3]赋值给一个变量,并尝试更改它:

In [188]: m1 = m[3]    
In [189]: m1
Out[189]: masked    
In [190]: m1[m1.mask]
Out[190]: 
masked_array(data=[--],
             mask=[ True],
       fill_value=1e+20,
            dtype=float64)

In [191]: m1[m1.mask] = -99
---------------------------------------------------------------------------
MaskError                                 Traceback (most recent call last)
Cell In[191], line 1
----> 1 m1[m1.mask] = -99

File ~\anaconda3\lib\site-packages\numpy\ma\core.py:3348, in MaskedArray.__setitem__(self, indx, value)
   3340 """
   3341 x.__setitem__(i, y) <==> x[i]=y
   3342 
   (...)
   3345 
   3346 """
   3347 if self is masked:
-> 3348     raise MaskError('Cannot alter the masked element.')
   3349 _data = self._data
   3350 _mask = self._mask

MaskError: Cannot alter the masked element.

m1[...] = -99也不起作用。
如果我尝试直接修改m[i],而不是赋值m1,我可以更改所有屏蔽值:

In [195]: for i in range(5):
     ...:     if np.ma.isMaskedArray(m[i]): m[i]=-99
     ...:     
In [196]: m
Out[196]: 
masked_array(data=[0.0, -99.0, 2.0, -99.0, 4.0],
             mask=[False, False, False, False, False],
       fill_value=1e+20)

但是我想知道你是否只需要使用filled

In [207]: m
Out[207]: 
masked_array(data=[0.0, --, 2.0, --, 4.0],
             mask=[False,  True, False,  True, False],
       fill_value=1e+20)

In [208]: m2 = m.filled(-99)
In [209]: m2
Out[209]: array([  0., -99.,   2., -99.,   4.])

相关问题