Reputation: 233
I have 20 netCDF files from WRF model (different runs) and I'm want to get slp variable from all these files and put into only one xarray.DataArray.
After reading the first file, I used expand_dims to add a new dimension. So, after that I tried to assign values obtained from the other files. However, I got the following error:
ValueError: assignment destination is read-only
Below is the code:
arq = nc.Dataset( dataDir+lista[0] )
dados = wrf.getvar( arq, 'slp', wrf.ALL_TIMES )
arq.close()
pnmm = dados.expand_dims( dim={ 'membro':Narqs } )
for membro in np.arange(1,20):
arq = nc.Dataset( dataDir+lista[ membro ] )
dummy = wrf.getvar( arq, 'slp', wrf.ALL_TIMES )
pnmm[ membro, :, :, :] = dummy
del dummy
arq.close()
here, Narqs is an integer variable with the number of netCDF files got from list lista which was obtained with os.listdir().
After expand_dims I'm getting the desirable array shape with an extra dimension for all data from all files. However, the line
pnmm[ membro, :, :, :] = dummy
is producing the error. I tried to assign just the values of dummy (with dummy.values), but didn't work because pnmm is read-only.
So,
1) Why pnmm DataArray is read-only? Is it truly read-only or I'm accessing its elements in a wrong way?
2) Is there a way to easily assign values to pnmm DataArray?
I've tried using xarray.concat and it works, but I really would like to understand why the above approach didn't work, because it seems much more intuitive. Also, with concat I have to create and delete more dummy variables to make it works.
UPDATE:
As I have written above, using xarray.concat solves my problem and I show the code below:
for membro in np.arange(0,20):
if membro == 0:
print( 'acessando arquivo 0' )
arq = nc.Dataset( dataDir+lista[ membro ] )
pnmm = wrf.getvar( arq, 'slp', wrf.ALL_TIMES )
arq.close()
else:
print( 'acessando arquivo '+str( membro ) )
arq = nc.Dataset( dataDir+lista[ membro ] )
d2 = wrf.getvar( arq, 'slp', wrf.ALL_TIMES )
arq.close()
d3 = xr.concat( [pnmm,d2], dim='membro' )
del pnmm, d2
pnmm = d3.copy()
del d3
However, even with this problem solved, I really would like to know how to do this in a simpler way, like using pnmm[ membro, :, :, :] = dummy. I also have tried other ways, like:
dados = wrf.getvar( arq, 'slp', wrf.ALL_TIMES )
pnmm = dados.copy( deep=True, data=None )
pnmm = dados.expand_dims( dim={ 'membro':Narqs } )
However, the read-only problem still rises.
In other words: I just want to get the structure of a DataArray from a netCDF file, add a new dimension to this structure and assign values to this new object.
Thank you.
Mateus
Upvotes: 2
Views: 1365
Reputation: 806
1) Why pnmm DataArray is read-only? Is it truly read-only or I'm accessing its elements in a wrong way?
It's ready only at this stage because it points directly to the netCDF file on disk.
2) Is there a way to easily assign values to pnmm DataArray?
My recommendation would be to use a more xarray-centric approach, avoiding the low-level netCDF4 library. You may be able to do exactly what you want in one line with xarray.open_mfdataset. Something like this:
ds = xr.open_mfdataset('/path/to/files/*.nc', concat_dim='member')
If this fails, you may need to add a preprocessing function, or open the files individually and then manually call xarray.concat on the resulting datasets.
Upvotes: 2