I am new to python and I am trying to convert python 2 code I found on github (https://github.com/RDCEP/psims) into python 3. It went quite well, but now I am stuck with the following error message:
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.
--
in the code source for numpy.ma.core it says:
if self is masked:
raise MaskError('Cannot alter the masked element.')
The code is
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
I understand why the error is raised, but I have no idea how to solve this. I am using python 3.7 and numpy version 1.24.1. Any help much appreciated. Thank you!
I see that
in my
setitem
.np.ma.masked
is aMaskedConstant
(documented)If looks like
vl = v[i, j, 0, 0]
, is an element of an arrayv
(unless the array is 5d).If I make a 1d masked array, and test elements:
however if I try to change a value: In [182]: m[1] Out[182]: masked In [183]: m[1]=-99 In [184]: m Out[184]: masked_array(data=[0.0, -99.0, 2.0, --, 4.0], mask=[False, False, False, True, False], fill_value=1e+20)
Note that
m[1]
is no longer masked.Now if instead of doing
m[3]=-99
, let's assignm[3]
to a variable, and try to change that:m1[...] = -99
doesn't work either.If instead of assigning
m1
, I tried to modifym[i]
directly I can change all masked values:But I wonder if you just need to use
filled
?