Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to multiply Python Xarray Datasets?

I am reading multiple netCDF formatted data files (WRF model output files) using xarray.open_mfdataset() function. I am reading and destaggering various variables such as Variable QVAPOR, U & V resp. I am using the following code for reading netCDF variables and computing resultant variable UQ.

import xarray as xr

def desta_var(pp,var):
    flnm = xr.open_mfdataset(pp)
    if var=="U":
        U1 = (flnm.variables[var])
        U = 0.5*(U1[:,:,:,0:-1] + U1[:,:,:,1:] )
        del U1
        return U
    elif var=="V":
        V1 = (flnm.variables[var])
        V=0.5*(V1[:,:,0:-1,:] + V1[:,:,1:,:])
        del V1
        return V
    else:
        W1 = (flnm.variables[var])
        W=0.5*(W1[:,0:-1,:,:] + W1[:,1:,:,:])
        del W1
        return W

 U=desta_var('./WRF_3D_2005_*.nc','U')
 V=desta_var('./WRF_3D_2005_*.nc','V')

 flnm=xr.open_mfdataset('./WRF_3D_2005_*.nc')

 QV = flnm.QVAPOR
 UQ = U*QV

Dimension and shape of variables obtained using above code:

The dimensions of wind variables Ex. U and its shape is

Times, lev, y, x_2 and it's shape is (1186, lev: 36, y: 699, x_2: 639)

The dimensions of Moisture variables Ex. QVAPOR and its shape is

Times, lev, y, x and it's shape is (1186, lev: 36, y: 699, x: 639)

After multiplying U and QVAPOR ; I compute UQ=U*QVAPOR. The dimension and shape of UQ is

Times, lev, y, x_2, x and shape is (Times: 1186, lev: 36, y: 699, x_2: 639, x: 639)

So the problem is as follows:

I am not able to get the dimensions correct. The correct dimensions of UQ should be Times, lev, y, x. Could anybody help me how to multiply xarray Datasets with different dimension names. I am not sure why do I get UQ variable with 5 dimension while U and QVAPOR are 4 dimension each.

like image 486
Sopan Kurkute Avatar asked Jan 02 '23 16:01

Sopan Kurkute


1 Answers

Unlike NumPy, Xarray matches up array dimensions by name, not position.

It loops over dimensions with different names in arithmetic, and your DataArray objects have different dimensions: [Times, lev, y, x_2] and [Times, lev, y, x].

The simple fix is to rename x_2 -> x on the first array before multiplying them together, e.g,. U.rename({'x_2': 'x'}) * QVAPOR.

(Note that you may also need to align or reindex the coordinate values along x_2 if they don't exactly match those along x. Something like U.rename({'x_2': 'x'}).reindex(x=QVAPOR.x, method='nearest', tolerance=123) should do the trick.)

like image 87
shoyer Avatar answered Jan 12 '23 09:01

shoyer